2 # Generate AutoGen.h, AutoGen.c and *.depex files
4 # Copyright (c) 2007 - 2010, Intel Corporation
5 # All rights reserved. This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
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 *
38 ## Regular expression for splitting Dependency Expression stirng into tokens
39 gDepexTokenPattern
= re
.compile("(\(|\)|\w+| \S+\.inf)")
41 ## Mapping Makefile type
42 gMakeTypeMap
= {"MSFT":"nmake", "GCC":"gmake"}
45 ## Build rule configuration file
46 gBuildRuleFile
= 'Conf/build_rule.txt'
48 ## default file name for AutoGen
49 gAutoGenCodeFileName
= "AutoGen.c"
50 gAutoGenHeaderFileName
= "AutoGen.h"
51 gAutoGenStringFileName
= "%(module_name)sStrDefs.h"
52 gAutoGenStringFormFileName
= "%(module_name)sStrDefs.hpk"
53 gAutoGenDepexFileName
= "%(module_name)s.depex"
55 ## Base class for AutoGen
57 # This class just implements the cache mechanism of AutoGen objects.
59 class AutoGen(object):
60 # database to maintain the objects of xxxAutoGen
61 _CACHE_
= {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}
65 # @param Class class object of real AutoGen class
66 # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
67 # @param Workspace Workspace directory or WorkspaceAutoGen object
68 # @param MetaFile The path of meta file
69 # @param Target Build target
70 # @param Toolchain Tool chain name
71 # @param Arch Target arch
72 # @param *args The specific class related parameters
73 # @param **kwargs The specific class related dict parameters
75 def __new__(Class
, Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
76 # check if the object has been created
77 Key
= (Target
, Toolchain
)
78 if Key
not in Class
._CACHE
_ or Arch
not in Class
._CACHE
_[Key
] \
79 or MetaFile
not in Class
._CACHE
_[Key
][Arch
]:
80 AutoGenObject
= super(AutoGen
, Class
).__new
__(Class
)
81 # call real constructor
82 if not AutoGenObject
._Init
(Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
84 if Key
not in Class
._CACHE
_:
85 Class
._CACHE
_[Key
] = {}
86 if Arch
not in Class
._CACHE
_[Key
]:
87 Class
._CACHE
_[Key
][Arch
] = {}
88 Class
._CACHE
_[Key
][Arch
][MetaFile
] = AutoGenObject
90 AutoGenObject
= Class
._CACHE
_[Key
][Arch
][MetaFile
]
96 # The file path of platform file will be used to represent hash value of this object
98 # @retval int Hash value of the file path of platform file
101 return hash(self
.MetaFile
)
105 # The file path of platform file will be used to represent this object
107 # @retval string String of platform file path
110 return str(self
.MetaFile
)
113 def __eq__(self
, Other
):
114 return Other
and self
.MetaFile
== Other
116 ## Workspace AutoGen class
118 # This class is used mainly to control the whole platform build for different
119 # architecture. This class will generate top level makefile.
121 class WorkspaceAutoGen(AutoGen
):
122 ## Real constructor of WorkspaceAutoGen
124 # This method behaves the same as __init__ except that it needs explict invoke
125 # (in super class's __new__ method)
127 # @param WorkspaceDir Root directory of workspace
128 # @param ActivePlatform Meta-file of active platform
129 # @param Target Build target
130 # @param Toolchain Tool chain name
131 # @param ArchList List of architecture of current build
132 # @param MetaFileDb Database containing meta-files
133 # @param BuildConfig Configuration of build
134 # @param ToolDefinition Tool chain definitions
135 # @param FlashDefinitionFile File of flash definition
136 # @param Fds FD list to be generated
137 # @param Fvs FV list to be generated
138 # @param SkuId SKU id from command line
140 def _Init(self
, WorkspaceDir
, ActivePlatform
, Target
, Toolchain
, ArchList
, MetaFileDb
,
141 BuildConfig
, ToolDefinition
, FlashDefinitionFile
='', Fds
=[], Fvs
=[], SkuId
='', UniFlag
=None):
142 self
.MetaFile
= ActivePlatform
.MetaFile
143 self
.WorkspaceDir
= WorkspaceDir
144 self
.Platform
= ActivePlatform
145 self
.BuildTarget
= Target
146 self
.ToolChain
= Toolchain
147 self
.ArchList
= ArchList
149 self
.UniFlag
= UniFlag
151 self
.BuildDatabase
= MetaFileDb
152 self
.TargetTxt
= BuildConfig
153 self
.ToolDef
= ToolDefinition
154 self
.FdfFile
= FlashDefinitionFile
155 self
.FdTargetList
= Fds
156 self
.FvTargetList
= Fvs
157 self
.AutoGenObjectList
= []
159 # there's many relative directory operations, so ...
160 os
.chdir(self
.WorkspaceDir
)
162 # parse FDF file to get PCDs in it, if any
163 if self
.FdfFile
!= None and self
.FdfFile
!= '':
164 Fdf
= FdfParser(self
.FdfFile
.Path
)
166 PcdSet
= Fdf
.Profile
.PcdDict
167 ModuleList
= Fdf
.Profile
.InfList
168 self
.FdfProfile
= Fdf
.Profile
172 self
.FdfProfile
= None
174 # apply SKU and inject PCDs from Flash Definition file
175 for Arch
in self
.ArchList
:
176 Platform
= self
.BuildDatabase
[self
.MetaFile
, Arch
]
177 Platform
.SkuName
= self
.SkuId
178 for Name
, Guid
in PcdSet
:
179 Platform
.AddPcd(Name
, Guid
, PcdSet
[Name
, Guid
])
181 Pa
= PlatformAutoGen(self
, self
.MetaFile
, Target
, Toolchain
, Arch
)
183 # Explicitly collect platform's dynamic PCDs
185 Pa
.CollectPlatformDynamicPcds()
186 self
.AutoGenObjectList
.append(Pa
)
188 self
._BuildDir
= None
190 self
._MakeFileDir
= None
191 self
._BuildCommand
= None
196 return "%s [%s]" % (self
.MetaFile
, ", ".join(self
.ArchList
))
198 ## Return the directory to store FV files
200 if self
._FvDir
== None:
201 self
._FvDir
= path
.join(self
.BuildDir
, 'FV')
204 ## Return the directory to store all intermediate and final files built
205 def _GetBuildDir(self
):
206 return self
.AutoGenObjectList
[0].BuildDir
208 ## Return the build output directory platform specifies
209 def _GetOutputDir(self
):
210 return self
.Platform
.OutputDirectory
212 ## Return platform name
214 return self
.Platform
.PlatformName
216 ## Return meta-file GUID
218 return self
.Platform
.Guid
220 ## Return platform version
221 def _GetVersion(self
):
222 return self
.Platform
.Version
224 ## Return paths of tools
225 def _GetToolDefinition(self
):
226 return self
.AutoGenObjectList
[0].ToolDefinition
228 ## Return directory of platform makefile
230 # @retval string Makefile directory
232 def _GetMakeFileDir(self
):
233 if self
._MakeFileDir
== None:
234 self
._MakeFileDir
= self
.BuildDir
235 return self
._MakeFileDir
237 ## Return build command string
239 # @retval string Build command string
241 def _GetBuildCommand(self
):
242 if self
._BuildCommand
== None:
243 # BuildCommand should be all the same. So just get one from platform AutoGen
244 self
._BuildCommand
= self
.AutoGenObjectList
[0].BuildCommand
245 return self
._BuildCommand
247 ## Create makefile for the platform and mdoules in it
249 # @param CreateDepsMakeFile Flag indicating if the makefile for
250 # modules will be created as well
252 def CreateMakeFile(self
, CreateDepsMakeFile
=False):
253 # create makefile for platform
254 Makefile
= GenMake
.TopLevelMakefile(self
)
255 if Makefile
.Generate():
256 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for platform [%s] %s\n" %
257 (self
.MetaFile
, self
.ArchList
))
259 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for platform [%s] %s\n" %
260 (self
.MetaFile
, self
.ArchList
))
262 if CreateDepsMakeFile
:
263 for Pa
in self
.AutoGenObjectList
:
264 Pa
.CreateMakeFile(CreateDepsMakeFile
)
266 ## Create autogen code for platform and modules
268 # Since there's no autogen code for platform, this method will do nothing
269 # if CreateModuleCodeFile is set to False.
271 # @param CreateDepsCodeFile Flag indicating if creating module's
272 # autogen code file or not
274 def CreateCodeFile(self
, CreateDepsCodeFile
=False):
275 if not CreateDepsCodeFile
:
277 for Pa
in self
.AutoGenObjectList
:
278 Pa
.CreateCodeFile(CreateDepsCodeFile
)
280 Name
= property(_GetName
)
281 Guid
= property(_GetGuid
)
282 Version
= property(_GetVersion
)
283 OutputDir
= property(_GetOutputDir
)
285 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
287 BuildDir
= property(_GetBuildDir
)
288 FvDir
= property(_GetFvDir
)
289 MakeFileDir
= property(_GetMakeFileDir
)
290 BuildCommand
= property(_GetBuildCommand
)
292 ## AutoGen class for platform
294 # PlatformAutoGen class will process the original information in platform
295 # file in order to generate makefile for platform.
297 class PlatformAutoGen(AutoGen
):
299 # Used to store all PCDs for both PEI and DXE phase, in order to generate
300 # correct PCD database
303 _NonDynaPcdList_
= []
305 ## The real constructor of PlatformAutoGen
307 # This method is not supposed to be called by users of PlatformAutoGen. It's
308 # only used by factory method __new__() to do real initialization work for an
309 # object of PlatformAutoGen
311 # @param Workspace WorkspaceAutoGen object
312 # @param PlatformFile Platform file (DSC file)
313 # @param Target Build target (DEBUG, RELEASE)
314 # @param Toolchain Name of tool chain
315 # @param Arch arch of the platform supports
317 def _Init(self
, Workspace
, PlatformFile
, Target
, Toolchain
, Arch
):
318 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen platform [%s] [%s]" % (PlatformFile
, Arch
))
319 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (PlatformFile
, Arch
, Toolchain
, Target
)
321 self
.MetaFile
= PlatformFile
322 self
.Workspace
= Workspace
323 self
.WorkspaceDir
= Workspace
.WorkspaceDir
324 self
.ToolChain
= Toolchain
325 self
.BuildTarget
= Target
327 self
.SourceDir
= PlatformFile
.SubDir
328 self
.SourceOverrideDir
= None
329 self
.FdTargetList
= self
.Workspace
.FdTargetList
330 self
.FvTargetList
= self
.Workspace
.FvTargetList
333 # flag indicating if the makefile/C-code file has been created or not
334 self
.IsMakeFileCreated
= False
335 self
.IsCodeFileCreated
= False
337 self
._Platform
= None
342 self
._BuildRule
= None
343 self
._SourceDir
= None
344 self
._BuildDir
= None
345 self
._OutputDir
= None
347 self
._MakeFileDir
= None
350 self
._PcdTokenNumber
= None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
351 self
._DynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
352 self
._NonDynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
354 self
._ToolDefinitions
= None
355 self
._ToolDefFile
= None # toolcode : tool path
356 self
._ToolChainFamily
= None
357 self
._BuildRuleFamily
= None
358 self
._BuildOption
= None # toolcode : option
359 self
._EdkBuildOption
= None # edktoolcode : option
360 self
._EdkIIBuildOption
= None # edkiitoolcode : option
361 self
._PackageList
= None
362 self
._ModuleAutoGenList
= None
363 self
._LibraryAutoGenList
= None
364 self
._BuildCommand
= None
366 # get the original module/package/platform objects
367 self
.BuildDatabase
= Workspace
.BuildDatabase
371 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
373 ## Create autogen code for platform and modules
375 # Since there's no autogen code for platform, this method will do nothing
376 # if CreateModuleCodeFile is set to False.
378 # @param CreateModuleCodeFile Flag indicating if creating module's
379 # autogen code file or not
381 def CreateCodeFile(self
, CreateModuleCodeFile
=False):
382 # only module has code to be greated, so do nothing if CreateModuleCodeFile is False
383 if self
.IsCodeFileCreated
or not CreateModuleCodeFile
:
386 for Ma
in self
.ModuleAutoGenList
:
387 Ma
.CreateCodeFile(True)
389 # don't do this twice
390 self
.IsCodeFileCreated
= True
392 ## Create makefile for the platform and mdoules in it
394 # @param CreateModuleMakeFile Flag indicating if the makefile for
395 # modules will be created as well
397 def CreateMakeFile(self
, CreateModuleMakeFile
=False):
398 if CreateModuleMakeFile
:
399 for ModuleFile
in self
.Platform
.Modules
:
400 Ma
= ModuleAutoGen(self
.Workspace
, ModuleFile
, self
.BuildTarget
,
401 self
.ToolChain
, self
.Arch
, self
.MetaFile
)
402 Ma
.CreateMakeFile(True)
404 # no need to create makefile for the platform more than once
405 if self
.IsMakeFileCreated
:
408 # create makefile for platform
409 Makefile
= GenMake
.PlatformMakefile(self
)
410 if Makefile
.Generate():
411 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for platform [%s] [%s]\n" %
412 (self
.MetaFile
, self
.Arch
))
414 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for platform [%s] [%s]\n" %
415 (self
.MetaFile
, self
.Arch
))
416 self
.IsMakeFileCreated
= True
418 ## Collect dynamic PCDs
420 # Gather dynamic PCDs list from each module and their settings from platform
421 # This interface should be invoked explicitly when platform action is created.
423 def CollectPlatformDynamicPcds(self
):
424 # for gathering error information
425 NoDatumTypePcdList
= set()
428 for F
in self
.Platform
.Modules
.keys():
429 M
= ModuleAutoGen(self
.Workspace
, F
, self
.BuildTarget
, self
.ToolChain
, self
.Arch
, self
.MetaFile
)
430 #GuidValue.update(M.Guids)
432 self
.Platform
.Modules
[F
].M
= M
434 for PcdFromModule
in M
.ModulePcdList
+M
.LibraryPcdList
:
435 # make sure that the "VOID*" kind of datum has MaxDatumSize set
436 if PcdFromModule
.DatumType
== "VOID*" and PcdFromModule
.MaxDatumSize
== None:
437 NoDatumTypePcdList
.add("%s.%s [%s]" % (PcdFromModule
.TokenSpaceGuidCName
, PcdFromModule
.TokenCName
, F
))
439 if PcdFromModule
.Type
in GenC
.gDynamicPcd
or PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
441 # If a dynamic PCD used by a PEM module/PEI module & DXE module,
442 # it should be stored in Pcd PEI database, If a dynamic only
443 # used by DXE module, it should be stored in DXE PCD database.
444 # The default Phase is DXE
446 if M
.ModuleType
in ["PEIM", "PEI_CORE"]:
447 PcdFromModule
.Phase
= "PEI"
448 if PcdFromModule
not in self
._DynaPcdList
_:
449 self
._DynaPcdList
_.append(PcdFromModule
)
450 elif PcdFromModule
.Phase
== 'PEI':
451 # overwrite any the same PCD existing, if Phase is PEI
452 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
453 self
._DynaPcdList
_[Index
] = PcdFromModule
454 elif PcdFromModule
not in self
._NonDynaPcdList
_:
455 self
._NonDynaPcdList
_.append(PcdFromModule
)
457 # print out error information and break the build, if error found
458 if len(NoDatumTypePcdList
) > 0:
459 NoDatumTypePcdListString
= "\n\t\t".join(NoDatumTypePcdList
)
460 EdkLogger
.error("build", AUTOGEN_ERROR
, "PCD setting error",
462 ExtraData
="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
463 % NoDatumTypePcdListString
)
464 self
._NonDynamicPcdList
= self
._NonDynaPcdList
_
465 self
._DynamicPcdList
= self
._DynaPcdList
_
466 self
.AllPcdList
= self
._NonDynamicPcdList
+ self
._DynamicPcdList
469 # Sort dynamic PCD list to:
470 # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should
471 # try to be put header of dynamicd List
472 # 2) If PCD is HII type, the PCD item should be put after unicode type PCD
474 # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.
479 for Pcd
in self
._DynamicPcdList
:
480 # just pick the a value to determine whether is unicode string type
481 Sku
= Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]]
482 PcdValue
= Sku
.DefaultValue
483 if Pcd
.DatumType
== 'VOID*' and PcdValue
.startswith("L"):
484 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
485 UnicodePcdArray
.append(Pcd
)
486 elif len(Sku
.VariableName
) > 0:
487 # if found HII type PCD then insert to right of UnicodeIndex
488 HiiPcdArray
.append(Pcd
)
490 OtherPcdArray
.append(Pcd
)
491 del self
._DynamicPcdList
[:]
492 self
._DynamicPcdList
.extend(UnicodePcdArray
)
493 self
._DynamicPcdList
.extend(HiiPcdArray
)
494 self
._DynamicPcdList
.extend(OtherPcdArray
)
497 ## Return the platform build data object
498 def _GetPlatform(self
):
499 if self
._Platform
== None:
500 self
._Platform
= self
.BuildDatabase
[self
.MetaFile
, self
.Arch
]
501 return self
._Platform
503 ## Return platform name
505 return self
.Platform
.PlatformName
507 ## Return the meta file GUID
509 return self
.Platform
.Guid
511 ## Return the platform version
512 def _GetVersion(self
):
513 return self
.Platform
.Version
515 ## Return the FDF file name
516 def _GetFdfFile(self
):
517 if self
._FdfFile
== None:
518 if self
.Workspace
.FdfFile
!= "":
519 self
._FdfFile
= path
.join(self
.WorkspaceDir
, self
.Workspace
.FdfFile
)
524 ## Return the build output directory platform specifies
525 def _GetOutputDir(self
):
526 return self
.Platform
.OutputDirectory
528 ## Return the directory to store all intermediate and final files built
529 def _GetBuildDir(self
):
530 if self
._BuildDir
== None:
531 if os
.path
.isabs(self
.OutputDir
):
532 self
._BuildDir
= path
.join(
533 path
.abspath(self
.OutputDir
),
534 self
.BuildTarget
+ "_" + self
.ToolChain
,
537 self
._BuildDir
= path
.join(
540 self
.BuildTarget
+ "_" + self
.ToolChain
,
542 return self
._BuildDir
544 ## Return directory of platform makefile
546 # @retval string Makefile directory
548 def _GetMakeFileDir(self
):
549 if self
._MakeFileDir
== None:
550 self
._MakeFileDir
= path
.join(self
.BuildDir
, self
.Arch
)
551 return self
._MakeFileDir
553 ## Return build command string
555 # @retval string Build command string
557 def _GetBuildCommand(self
):
558 if self
._BuildCommand
== None:
559 self
._BuildCommand
= []
560 if "MAKE" in self
.ToolDefinition
and "PATH" in self
.ToolDefinition
["MAKE"]:
561 self
._BuildCommand
+= SplitOption(self
.ToolDefinition
["MAKE"]["PATH"])
562 if "FLAGS" in self
.ToolDefinition
["MAKE"]:
563 NewOption
= self
.ToolDefinition
["MAKE"]["FLAGS"].strip()
565 self
._BuildCommand
+= SplitOption(NewOption
)
566 return self
._BuildCommand
568 ## Get tool chain definition
570 # Get each tool defition for given tool chain from tools_def.txt and platform
572 def _GetToolDefinition(self
):
573 if self
._ToolDefinitions
== None:
574 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDictionary
575 if TAB_TOD_DEFINES_COMMAND_TYPE
not in self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
:
576 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No tools found in configuration",
577 ExtraData
="[%s]" % self
.MetaFile
)
578 self
._ToolDefinitions
= {}
580 for Def
in ToolDefinition
:
581 Target
, Tag
, Arch
, Tool
, Attr
= Def
.split("_")
582 if Target
!= self
.BuildTarget
or Tag
!= self
.ToolChain
or Arch
!= self
.Arch
:
585 Value
= ToolDefinition
[Def
]
586 # don't record the DLL
588 DllPathList
.add(Value
)
591 if Tool
not in self
._ToolDefinitions
:
592 self
._ToolDefinitions
[Tool
] = {}
593 self
._ToolDefinitions
[Tool
][Attr
] = Value
597 if GlobalData
.gOptions
.SilentMode
and "MAKE" in self
._ToolDefinitions
:
598 if "FLAGS" not in self
._ToolDefinitions
["MAKE"]:
599 self
._ToolDefinitions
["MAKE"]["FLAGS"] = ""
600 self
._ToolDefinitions
["MAKE"]["FLAGS"] += " -s"
602 for Tool
in self
._ToolDefinitions
:
603 for Attr
in self
._ToolDefinitions
[Tool
]:
604 Value
= self
._ToolDefinitions
[Tool
][Attr
]
605 if Tool
in self
.BuildOption
and Attr
in self
.BuildOption
[Tool
]:
606 # check if override is indicated
607 if self
.BuildOption
[Tool
][Attr
].startswith('='):
608 Value
= self
.BuildOption
[Tool
][Attr
][1:]
610 Value
+= " " + self
.BuildOption
[Tool
][Attr
]
613 # Don't put MAKE definition in the file
617 ToolsDef
+= "%s = %s\n" % (Tool
, Value
)
619 # Don't put MAKE definition in the file
624 ToolsDef
+= "%s_%s = %s\n" % (Tool
, Attr
, Value
)
627 SaveFileOnChange(self
.ToolDefinitionFile
, ToolsDef
)
628 for DllPath
in DllPathList
:
629 os
.environ
["PATH"] = DllPath
+ os
.pathsep
+ os
.environ
["PATH"]
630 os
.environ
["MAKE_FLAGS"] = MakeFlags
632 return self
._ToolDefinitions
634 ## Return the paths of tools
635 def _GetToolDefFile(self
):
636 if self
._ToolDefFile
== None:
637 self
._ToolDefFile
= os
.path
.join(self
.MakeFileDir
, "TOOLS_DEF." + self
.Arch
)
638 return self
._ToolDefFile
640 ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.
641 def _GetToolChainFamily(self
):
642 if self
._ToolChainFamily
== None:
643 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
644 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
645 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
646 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]:
647 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
649 self
._ToolChainFamily
= "MSFT"
651 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]
652 return self
._ToolChainFamily
654 def _GetBuildRuleFamily(self
):
655 if self
._BuildRuleFamily
== None:
656 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
657 if TAB_TOD_DEFINES_BUILDRULEFAMILY
not in ToolDefinition \
658 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
] \
659 or not ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]:
660 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
662 self
._BuildRuleFamily
= "MSFT"
664 self
._BuildRuleFamily
= ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]
665 return self
._BuildRuleFamily
667 ## Return the build options specific for all modules in this platform
668 def _GetBuildOptions(self
):
669 if self
._BuildOption
== None:
670 self
._BuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
)
671 return self
._BuildOption
673 ## Return the build options specific for EDK modules in this platform
674 def _GetEdkBuildOptions(self
):
675 if self
._EdkBuildOption
== None:
676 self
._EdkBuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
, EDK_NAME
)
677 return self
._EdkBuildOption
679 ## Return the build options specific for EDKII modules in this platform
680 def _GetEdkIIBuildOptions(self
):
681 if self
._EdkIIBuildOption
== None:
682 self
._EdkIIBuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
, EDKII_NAME
)
683 return self
._EdkIIBuildOption
685 ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt
687 # @retval BuildRule object
689 def _GetBuildRule(self
):
690 if self
._BuildRule
== None:
692 if TAB_TAT_DEFINES_BUILD_RULE_CONF
in self
.Workspace
.TargetTxt
.TargetTxtDictionary
:
693 BuildRuleFile
= self
.Workspace
.TargetTxt
.TargetTxtDictionary
[TAB_TAT_DEFINES_BUILD_RULE_CONF
]
694 if BuildRuleFile
in [None, '']:
695 BuildRuleFile
= gBuildRuleFile
696 self
._BuildRule
= BuildRule(BuildRuleFile
)
697 return self
._BuildRule
699 ## Summarize the packages used by modules in this platform
700 def _GetPackageList(self
):
701 if self
._PackageList
== None:
702 self
._PackageList
= set()
703 for La
in self
.LibraryAutoGenList
:
704 self
._PackageList
.update(La
.DependentPackageList
)
705 for Ma
in self
.ModuleAutoGenList
:
706 self
._PackageList
.update(Ma
.DependentPackageList
)
707 self
._PackageList
= list(self
._PackageList
)
708 return self
._PackageList
710 ## Get list of non-dynamic PCDs
711 def _GetNonDynamicPcdList(self
):
712 return self
._NonDynamicPcdList
714 ## Get list of dynamic PCDs
715 def _GetDynamicPcdList(self
):
716 return self
._DynamicPcdList
718 ## Generate Token Number for all PCD
719 def _GetPcdTokenNumbers(self
):
720 if self
._PcdTokenNumber
== None:
721 self
._PcdTokenNumber
= sdict()
723 for Pcd
in self
.DynamicPcdList
:
724 if Pcd
.Phase
== "PEI":
725 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
726 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
729 for Pcd
in self
.DynamicPcdList
:
730 if Pcd
.Phase
== "DXE":
731 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
732 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
735 for Pcd
in self
.NonDynamicPcdList
:
736 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
738 return self
._PcdTokenNumber
740 ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform
741 def _GetAutoGenObjectList(self
):
742 self
._ModuleAutoGenList
= []
743 self
._LibraryAutoGenList
= []
744 for ModuleFile
in self
.Platform
.Modules
:
753 if Ma
not in self
._ModuleAutoGenList
:
754 self
._ModuleAutoGenList
.append(Ma
)
755 for La
in Ma
.LibraryAutoGenList
:
756 if La
not in self
._LibraryAutoGenList
:
757 self
._LibraryAutoGenList
.append(La
)
759 ## Summarize ModuleAutoGen objects of all modules to be built for this platform
760 def _GetModuleAutoGenList(self
):
761 if self
._ModuleAutoGenList
== None:
762 self
._GetAutoGenObjectList
()
763 return self
._ModuleAutoGenList
765 ## Summarize ModuleAutoGen objects of all libraries to be built for this platform
766 def _GetLibraryAutoGenList(self
):
767 if self
._LibraryAutoGenList
== None:
768 self
._GetAutoGenObjectList
()
769 return self
._LibraryAutoGenList
771 ## Test if a module is supported by the platform
773 # An error will be raised directly if the module or its arch is not supported
774 # by the platform or current configuration
776 def ValidModule(self
, Module
):
777 return Module
in self
.Platform
.Modules
or Module
in self
.Platform
.LibraryInstances
779 ## Resolve the library classes in a module to library instances
781 # This method will not only resolve library classes but also sort the library
782 # instances according to the dependency-ship.
784 # @param Module The module from which the library classes will be resolved
786 # @retval library_list List of library instances sorted
788 def ApplyLibraryInstance(self
, Module
):
789 ModuleType
= Module
.ModuleType
791 # for overridding library instances with module specific setting
792 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
794 # add forced library instances (specified under LibraryClasses sections)
795 for LibraryClass
in self
.Platform
.LibraryClasses
.GetKeys():
796 if LibraryClass
.startswith("NULL"):
797 Module
.LibraryClasses
[LibraryClass
] = self
.Platform
.LibraryClasses
[LibraryClass
]
799 # add forced library instances (specified in module overrides)
800 for LibraryClass
in PlatformModule
.LibraryClasses
:
801 if LibraryClass
.startswith("NULL"):
802 Module
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
805 LibraryConsumerList
= [Module
]
807 ConsumedByList
= sdict()
808 LibraryInstance
= sdict()
810 EdkLogger
.verbose("")
811 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
812 while len(LibraryConsumerList
) > 0:
813 M
= LibraryConsumerList
.pop()
814 for LibraryClassName
in M
.LibraryClasses
:
815 if LibraryClassName
not in LibraryInstance
:
816 # override library instance for this module
817 if LibraryClassName
in PlatformModule
.LibraryClasses
:
818 LibraryPath
= PlatformModule
.LibraryClasses
[LibraryClassName
]
820 LibraryPath
= self
.Platform
.LibraryClasses
[LibraryClassName
, ModuleType
]
821 if LibraryPath
== None or LibraryPath
== "":
822 LibraryPath
= M
.LibraryClasses
[LibraryClassName
]
823 if LibraryPath
== None or LibraryPath
== "":
824 EdkLogger
.error("build", RESOURCE_NOT_AVAILABLE
,
825 "Instance of library class [%s] is not found" % LibraryClassName
,
827 ExtraData
="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M
), self
.Arch
, str(Module
)))
829 LibraryModule
= self
.BuildDatabase
[LibraryPath
, self
.Arch
]
830 # for those forced library instance (NULL library), add a fake library class
831 if LibraryClassName
.startswith("NULL"):
832 LibraryModule
.LibraryClass
.append(LibraryClassObject(LibraryClassName
, [ModuleType
]))
833 elif LibraryModule
.LibraryClass
== None \
834 or len(LibraryModule
.LibraryClass
) == 0 \
835 or (ModuleType
!= 'USER_DEFINED'
836 and ModuleType
not in LibraryModule
.LibraryClass
[0].SupModList
):
837 # only USER_DEFINED can link against any library instance despite of its SupModList
838 EdkLogger
.error("build", OPTION_MISSING
,
839 "Module type [%s] is not supported by library instance [%s]" \
840 % (ModuleType
, LibraryPath
), File
=self
.MetaFile
,
841 ExtraData
="consumed by [%s]" % str(Module
))
843 LibraryInstance
[LibraryClassName
] = LibraryModule
844 LibraryConsumerList
.append(LibraryModule
)
845 EdkLogger
.verbose("\t" + str(LibraryClassName
) + " : " + str(LibraryModule
))
847 LibraryModule
= LibraryInstance
[LibraryClassName
]
849 if LibraryModule
== None:
852 if LibraryModule
.ConstructorList
!= [] and LibraryModule
not in Constructor
:
853 Constructor
.append(LibraryModule
)
855 if LibraryModule
not in ConsumedByList
:
856 ConsumedByList
[LibraryModule
] = []
857 # don't add current module itself to consumer list
859 if M
in ConsumedByList
[LibraryModule
]:
861 ConsumedByList
[LibraryModule
].append(M
)
863 # Initialize the sorted output list to the empty set
865 SortedLibraryList
= []
867 # Q <- Set of all nodes with no incoming edges
869 LibraryList
= [] #LibraryInstance.values()
871 for LibraryClassName
in LibraryInstance
:
872 M
= LibraryInstance
[LibraryClassName
]
873 LibraryList
.append(M
)
874 if ConsumedByList
[M
] == []:
878 # start the DAG algorithm
882 while Q
== [] and EdgeRemoved
:
884 # for each node Item with a Constructor
885 for Item
in LibraryList
:
886 if Item
not in Constructor
:
888 # for each Node without a constructor with an edge e from Item to Node
889 for Node
in ConsumedByList
[Item
]:
890 if Node
in Constructor
:
892 # remove edge e from the graph if Node has no constructor
893 ConsumedByList
[Item
].remove(Node
)
895 if ConsumedByList
[Item
] == []:
901 # DAG is done if there's no more incoming edge for all nodes
908 SortedLibraryList
.append(Node
)
910 # for each node Item with an edge e from Node to Item do
911 for Item
in LibraryList
:
912 if Node
not in ConsumedByList
[Item
]:
914 # remove edge e from the graph
915 ConsumedByList
[Item
].remove(Node
)
917 if ConsumedByList
[Item
] != []:
919 # insert Item into Q, if Item has no other incoming edges
923 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
925 for Item
in LibraryList
:
926 if ConsumedByList
[Item
] != [] and Item
in Constructor
and len(Constructor
) > 1:
927 ErrorMessage
= "\tconsumed by " + "\n\tconsumed by ".join([str(L
) for L
in ConsumedByList
[Item
]])
928 EdkLogger
.error("build", BUILD_ERROR
, 'Library [%s] with constructors has a cycle' % str(Item
),
929 ExtraData
=ErrorMessage
, File
=self
.MetaFile
)
930 if Item
not in SortedLibraryList
:
931 SortedLibraryList
.append(Item
)
934 # Build the list of constructor and destructir names
935 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
937 SortedLibraryList
.reverse()
938 return SortedLibraryList
941 ## Override PCD setting (type, value, ...)
943 # @param ToPcd The PCD to be overrided
944 # @param FromPcd The PCD overrideing from
946 def _OverridePcd(self
, ToPcd
, FromPcd
, Module
=""):
948 # in case there's PCDs coming from FDF file, which have no type given.
949 # at this point, ToPcd.Type has the type found from dependent
953 if ToPcd
.Pending
and FromPcd
.Type
not in [None, '']:
954 ToPcd
.Type
= FromPcd
.Type
955 elif ToPcd
.Type
not in [None, ''] and FromPcd
.Type
not in [None, ''] \
956 and ToPcd
.Type
!= FromPcd
.Type
:
957 EdkLogger
.error("build", OPTION_CONFLICT
, "Mismatched PCD type",
958 ExtraData
="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
959 % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
,
960 ToPcd
.Type
, Module
, FromPcd
.Type
),
963 if FromPcd
.MaxDatumSize
not in [None, '']:
964 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
965 if FromPcd
.DefaultValue
not in [None, '']:
966 ToPcd
.DefaultValue
= FromPcd
.DefaultValue
967 if FromPcd
.TokenValue
not in [None, '']:
968 ToPcd
.TokenValue
= FromPcd
.TokenValue
969 if FromPcd
.MaxDatumSize
not in [None, '']:
970 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
971 if FromPcd
.DatumType
not in [None, '']:
972 ToPcd
.DatumType
= FromPcd
.DatumType
973 if FromPcd
.SkuInfoList
not in [None, '', []]:
974 ToPcd
.SkuInfoList
= FromPcd
.SkuInfoList
976 # check the validation of datum
977 IsValid
, Cause
= CheckPcdDatum(ToPcd
.DatumType
, ToPcd
.DefaultValue
)
979 EdkLogger
.error('build', FORMAT_INVALID
, Cause
, File
=self
.MetaFile
,
980 ExtraData
="%s.%s" % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
))
982 if ToPcd
.DatumType
== "VOID*" and ToPcd
.MaxDatumSize
in ['', None]:
983 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "No MaxDatumSize specified for PCD %s.%s" \
984 % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
))
985 Value
= ToPcd
.DefaultValue
986 if Value
in [None, '']:
987 ToPcd
.MaxDatumSize
= 1
988 elif Value
[0] == 'L':
989 ToPcd
.MaxDatumSize
= str(len(Value
) * 2)
990 elif Value
[0] == '{':
991 ToPcd
.MaxDatumSize
= str(len(Value
.split(',')))
993 ToPcd
.MaxDatumSize
= str(len(Value
))
995 # apply default SKU for dynamic PCDS if specified one is not available
996 if (ToPcd
.Type
in PCD_DYNAMIC_TYPE_LIST
or ToPcd
.Type
in PCD_DYNAMIC_EX_TYPE_LIST
) \
997 and ToPcd
.SkuInfoList
in [None, {}, '']:
998 if self
.Platform
.SkuName
in self
.Platform
.SkuIds
:
999 SkuName
= self
.Platform
.SkuName
1002 ToPcd
.SkuInfoList
= {
1003 SkuName
: SkuInfoClass(SkuName
, self
.Platform
.SkuIds
[SkuName
], '', '', '', '', '', ToPcd
.DefaultValue
)
1006 ## Apply PCD setting defined platform to a module
1008 # @param Module The module from which the PCD setting will be overrided
1010 # @retval PCD_list The list PCDs with settings from platform
1012 def ApplyPcdSetting(self
, Module
, Pcds
):
1013 # for each PCD in module
1014 for Name
,Guid
in Pcds
:
1015 PcdInModule
= Pcds
[Name
,Guid
]
1016 # find out the PCD setting in platform
1017 if (Name
,Guid
) in self
.Platform
.Pcds
:
1018 PcdInPlatform
= self
.Platform
.Pcds
[Name
,Guid
]
1020 PcdInPlatform
= None
1021 # then override the settings if any
1022 self
._OverridePcd
(PcdInModule
, PcdInPlatform
, Module
)
1023 # resolve the VariableGuid value
1024 for SkuId
in PcdInModule
.SkuInfoList
:
1025 Sku
= PcdInModule
.SkuInfoList
[SkuId
]
1026 if Sku
.VariableGuid
== '': continue
1027 Sku
.VariableGuidValue
= GuidValue(Sku
.VariableGuid
, self
.PackageList
)
1028 if Sku
.VariableGuidValue
== None:
1029 PackageList
= "\n\t".join([str(P
) for P
in self
.PackageList
])
1032 RESOURCE_NOT_AVAILABLE
,
1033 "Value of GUID [%s] is not found in" % Sku
.VariableGuid
,
1034 ExtraData
=PackageList
+ "\n\t(used with %s.%s from module %s)" \
1035 % (Guid
, Name
, str(Module
)),
1039 # override PCD settings with module specific setting
1040 if Module
in self
.Platform
.Modules
:
1041 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1042 for Key
in PlatformModule
.Pcds
:
1044 self
._OverridePcd
(Pcds
[Key
], PlatformModule
.Pcds
[Key
], Module
)
1045 return Pcds
.values()
1047 ## Resolve library names to library modules
1049 # (for R8.x modules)
1051 # @param Module The module from which the library names will be resolved
1053 # @retval library_list The list of library modules
1055 def ResolveLibraryReference(self
, Module
):
1056 EdkLogger
.verbose("")
1057 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
1058 LibraryConsumerList
= [Module
]
1060 # "CompilerStub" is a must for R8 modules
1061 if Module
.Libraries
:
1062 Module
.Libraries
.append("CompilerStub")
1064 while len(LibraryConsumerList
) > 0:
1065 M
= LibraryConsumerList
.pop()
1066 for LibraryName
in M
.Libraries
:
1067 Library
= self
.Platform
.LibraryClasses
[LibraryName
, ':dummy:']
1069 for Key
in self
.Platform
.LibraryClasses
.data
.keys():
1070 if LibraryName
.upper() == Key
.upper():
1071 Library
= self
.Platform
.LibraryClasses
[Key
, ':dummy:']
1074 EdkLogger
.warn("build", "Library [%s] is not found" % LibraryName
, File
=str(M
),
1075 ExtraData
="\t%s [%s]" % (str(Module
), self
.Arch
))
1078 if Library
not in LibraryList
:
1079 LibraryList
.append(Library
)
1080 LibraryConsumerList
.append(Library
)
1081 EdkLogger
.verbose("\t" + LibraryName
+ " : " + str(Library
) + ' ' + str(type(Library
)))
1084 ## Expand * in build option key
1086 # @param Options Options to be expanded
1088 # @retval options Options expanded
1090 def _ExpandBuildOption(self
, Options
, ModuleStyle
=None):
1095 if ModuleStyle
!= None and len (Key
) > 2:
1096 # Check Module style is EDK or EDKII.
1097 # Only append build option for the matched style module.
1098 if ModuleStyle
== EDK_NAME
and Key
[2] != EDK_NAME
:
1100 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
1103 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
1104 # if tool chain family doesn't match, skip it
1105 if Tool
in self
.ToolDefinition
and Family
!= "":
1106 FamilyIsNull
= False
1107 if self
.ToolDefinition
[Tool
].get(TAB_TOD_DEFINES_BUILDRULEFAMILY
, "") != "":
1108 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_BUILDRULEFAMILY
]:
1110 elif Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
1113 # expand any wildcard
1114 if Target
== "*" or Target
== self
.BuildTarget
:
1115 if Tag
== "*" or Tag
== self
.ToolChain
:
1116 if Arch
== "*" or Arch
== self
.Arch
:
1117 if Tool
not in BuildOptions
:
1118 BuildOptions
[Tool
] = {}
1119 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
]:
1120 BuildOptions
[Tool
][Attr
] = Options
[Key
]
1122 # append options for the same tool
1123 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
1124 # Build Option Family has been checked, which need't to be checked again for family.
1125 if FamilyMatch
or FamilyIsNull
:
1129 if ModuleStyle
!= None and len (Key
) > 2:
1130 # Check Module style is EDK or EDKII.
1131 # Only append build option for the matched style module.
1132 if ModuleStyle
== EDK_NAME
and Key
[2] != EDK_NAME
:
1134 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
1137 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
1138 # if tool chain family doesn't match, skip it
1139 if Tool
not in self
.ToolDefinition
or Family
=="":
1141 # option has been added before
1142 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
1145 # expand any wildcard
1146 if Target
== "*" or Target
== self
.BuildTarget
:
1147 if Tag
== "*" or Tag
== self
.ToolChain
:
1148 if Arch
== "*" or Arch
== self
.Arch
:
1149 if Tool
not in BuildOptions
:
1150 BuildOptions
[Tool
] = {}
1151 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
]:
1152 BuildOptions
[Tool
][Attr
] = Options
[Key
]
1154 # append options for the same tool
1155 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
1158 ## Append build options in platform to a module
1160 # @param Module The module to which the build options will be appened
1162 # @retval options The options appended with build options in platform
1164 def ApplyBuildOption(self
, Module
):
1165 # Get the different options for the different style module
1166 if Module
.AutoGenVersion
< 0x00010005:
1167 PlatformOptions
= self
.EdkBuildOption
1169 PlatformOptions
= self
.EdkIIBuildOption
1170 ModuleOptions
= self
._ExpandBuildOption
(Module
.BuildOptions
)
1171 if Module
in self
.Platform
.Modules
:
1172 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1173 PlatformModuleOptions
= self
._ExpandBuildOption
(PlatformModule
.BuildOptions
)
1175 PlatformModuleOptions
= {}
1177 AllTools
= set(ModuleOptions
.keys() + PlatformOptions
.keys() + PlatformModuleOptions
.keys() + self
.ToolDefinition
.keys())
1179 for Tool
in AllTools
:
1180 if Tool
not in BuildOptions
:
1181 BuildOptions
[Tool
] = {}
1183 for Options
in [self
.ToolDefinition
, ModuleOptions
, PlatformOptions
, PlatformModuleOptions
]:
1184 if Tool
not in Options
:
1186 for Attr
in Options
[Tool
]:
1187 Value
= Options
[Tool
][Attr
]
1188 if Attr
not in BuildOptions
[Tool
]:
1189 BuildOptions
[Tool
][Attr
] = ""
1190 # check if override is indicated
1191 if Value
.startswith('='):
1192 BuildOptions
[Tool
][Attr
] = Value
[1:]
1194 BuildOptions
[Tool
][Attr
] += " " + Value
1195 if Module
.AutoGenVersion
< 0x00010005 and self
.Workspace
.UniFlag
!= None:
1197 # Override UNI flag only for EDK module.
1199 if 'BUILD' not in BuildOptions
:
1200 BuildOptions
['BUILD'] = {}
1201 BuildOptions
['BUILD']['FLAGS'] = self
.Workspace
.UniFlag
1204 Platform
= property(_GetPlatform
)
1205 Name
= property(_GetName
)
1206 Guid
= property(_GetGuid
)
1207 Version
= property(_GetVersion
)
1209 OutputDir
= property(_GetOutputDir
)
1210 BuildDir
= property(_GetBuildDir
)
1211 MakeFileDir
= property(_GetMakeFileDir
)
1212 FdfFile
= property(_GetFdfFile
)
1214 PcdTokenNumber
= property(_GetPcdTokenNumbers
) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
1215 DynamicPcdList
= property(_GetDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1216 NonDynamicPcdList
= property(_GetNonDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1217 PackageList
= property(_GetPackageList
)
1219 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
1220 ToolDefinitionFile
= property(_GetToolDefFile
) # toolcode : lib path
1221 ToolChainFamily
= property(_GetToolChainFamily
)
1222 BuildRuleFamily
= property(_GetBuildRuleFamily
)
1223 BuildOption
= property(_GetBuildOptions
) # toolcode : option
1224 EdkBuildOption
= property(_GetEdkBuildOptions
) # edktoolcode : option
1225 EdkIIBuildOption
= property(_GetEdkIIBuildOptions
) # edkiitoolcode : option
1227 BuildCommand
= property(_GetBuildCommand
)
1228 BuildRule
= property(_GetBuildRule
)
1229 ModuleAutoGenList
= property(_GetModuleAutoGenList
)
1230 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
1232 ## ModuleAutoGen class
1234 # This class encapsules the AutoGen behaviors for the build tools. In addition to
1235 # the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according
1236 # to the [depex] section in module's inf file.
1238 class ModuleAutoGen(AutoGen
):
1239 ## The real constructor of ModuleAutoGen
1241 # This method is not supposed to be called by users of ModuleAutoGen. It's
1242 # only used by factory method __new__() to do real initialization work for an
1243 # object of ModuleAutoGen
1245 # @param Workspace EdkIIWorkspaceBuild object
1246 # @param ModuleFile The path of module file
1247 # @param Target Build target (DEBUG, RELEASE)
1248 # @param Toolchain Name of tool chain
1249 # @param Arch The arch the module supports
1250 # @param PlatformFile Platform meta-file
1252 def _Init(self
, Workspace
, ModuleFile
, Target
, Toolchain
, Arch
, PlatformFile
):
1253 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen module [%s] [%s]" % (ModuleFile
, Arch
))
1254 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (ModuleFile
, Arch
, Toolchain
, Target
)
1256 self
.Workspace
= Workspace
1257 self
.WorkspaceDir
= Workspace
.WorkspaceDir
1259 self
.MetaFile
= ModuleFile
1260 self
.PlatformInfo
= PlatformAutoGen(Workspace
, PlatformFile
, Target
, Toolchain
, Arch
)
1261 # check if this module is employed by active platform
1262 if not self
.PlatformInfo
.ValidModule(self
.MetaFile
):
1263 EdkLogger
.verbose("Module [%s] for [%s] is not employed by active platform\n" \
1264 % (self
.MetaFile
, Arch
))
1267 self
.SourceDir
= self
.MetaFile
.SubDir
1268 self
.SourceOverrideDir
= None
1269 # use overrided path defined in DSC file
1270 if self
.MetaFile
.Key
in GlobalData
.gOverrideDir
:
1271 self
.SourceOverrideDir
= GlobalData
.gOverrideDir
[self
.MetaFile
.Key
]
1273 self
.ToolChain
= Toolchain
1274 self
.BuildTarget
= Target
1276 self
.ToolChainFamily
= self
.PlatformInfo
.ToolChainFamily
1277 self
.BuildRuleFamily
= self
.PlatformInfo
.BuildRuleFamily
1279 self
.IsMakeFileCreated
= False
1280 self
.IsCodeFileCreated
= False
1282 self
.BuildDatabase
= self
.Workspace
.BuildDatabase
1287 self
._Version
= None
1288 self
._ModuleType
= None
1289 self
._ComponentType
= None
1290 self
._PcdIsDriver
= None
1291 self
._AutoGenVersion
= None
1292 self
._LibraryFlag
= None
1293 self
._CustomMakefile
= None
1296 self
._BuildDir
= None
1297 self
._OutputDir
= None
1298 self
._DebugDir
= None
1299 self
._MakeFileDir
= None
1301 self
._IncludePathList
= None
1302 self
._AutoGenFileList
= None
1303 self
._UnicodeFileList
= None
1304 self
._SourceFileList
= None
1305 self
._ObjectFileList
= None
1306 self
._BinaryFileList
= None
1308 self
._DependentPackageList
= None
1309 self
._DependentLibraryList
= None
1310 self
._LibraryAutoGenList
= None
1311 self
._DerivedPackageList
= None
1312 self
._ModulePcdList
= None
1313 self
._LibraryPcdList
= None
1314 self
._GuidList
= None
1315 self
._ProtocolList
= None
1316 self
._PpiList
= None
1317 self
._DepexList
= None
1318 self
._DepexExpressionList
= None
1319 self
._BuildOption
= None
1320 self
._BuildTargets
= None
1321 self
._IntroBuildTargetList
= None
1322 self
._FinalBuildTargetList
= None
1323 self
._FileTypes
= None
1324 self
._BuildRules
= None
1329 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
1331 # Macros could be used in build_rule.txt (also Makefile)
1332 def _GetMacros(self
):
1333 if self
._Macro
== None:
1334 self
._Macro
= sdict()
1335 self
._Macro
["WORKSPACE" ] = self
.WorkspaceDir
1336 self
._Macro
["MODULE_NAME" ] = self
.Name
1337 self
._Macro
["MODULE_GUID" ] = self
.Guid
1338 self
._Macro
["MODULE_VERSION" ] = self
.Version
1339 self
._Macro
["MODULE_TYPE" ] = self
.ModuleType
1340 self
._Macro
["MODULE_FILE" ] = str(self
.MetaFile
)
1341 self
._Macro
["MODULE_FILE_BASE_NAME" ] = self
.MetaFile
.BaseName
1342 self
._Macro
["MODULE_RELATIVE_DIR" ] = self
.SourceDir
1343 self
._Macro
["MODULE_DIR" ] = self
.SourceDir
1345 self
._Macro
["BASE_NAME" ] = self
.Name
1347 self
._Macro
["ARCH" ] = self
.Arch
1348 self
._Macro
["TOOLCHAIN" ] = self
.ToolChain
1349 self
._Macro
["TOOLCHAIN_TAG" ] = self
.ToolChain
1350 self
._Macro
["TARGET" ] = self
.BuildTarget
1352 self
._Macro
["BUILD_DIR" ] = self
.PlatformInfo
.BuildDir
1353 self
._Macro
["BIN_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
1354 self
._Macro
["LIB_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
1355 self
._Macro
["MODULE_BUILD_DIR" ] = self
.BuildDir
1356 self
._Macro
["OUTPUT_DIR" ] = self
.OutputDir
1357 self
._Macro
["DEBUG_DIR" ] = self
.DebugDir
1360 ## Return the module build data object
1361 def _GetModule(self
):
1362 if self
._Module
== None:
1363 self
._Module
= self
.Workspace
.BuildDatabase
[self
.MetaFile
, self
.Arch
]
1366 ## Return the module name
1367 def _GetBaseName(self
):
1368 return self
.Module
.BaseName
1370 ## Return the module SourceOverridePath
1371 def _GetSourceOverridePath(self
):
1372 return self
.Module
.SourceOverridePath
1374 ## Return the module meta-file GUID
1376 return self
.Module
.Guid
1378 ## Return the module version
1379 def _GetVersion(self
):
1380 return self
.Module
.Version
1382 ## Return the module type
1383 def _GetModuleType(self
):
1384 return self
.Module
.ModuleType
1386 ## Return the component type (for R8.x style of module)
1387 def _GetComponentType(self
):
1388 return self
.Module
.ComponentType
1390 ## Return the build type
1391 def _GetBuildType(self
):
1392 return self
.Module
.BuildType
1394 ## Return the PCD_IS_DRIVER setting
1395 def _GetPcdIsDriver(self
):
1396 return self
.Module
.PcdIsDriver
1398 ## Return the autogen version, i.e. module meta-file version
1399 def _GetAutoGenVersion(self
):
1400 return self
.Module
.AutoGenVersion
1402 ## Check if the module is library or not
1403 def _IsLibrary(self
):
1404 if self
._LibraryFlag
== None:
1405 if self
.Module
.LibraryClass
!= None and self
.Module
.LibraryClass
!= []:
1406 self
._LibraryFlag
= True
1408 self
._LibraryFlag
= False
1409 return self
._LibraryFlag
1411 ## Return the directory to store intermediate files of the module
1412 def _GetBuildDir(self
):
1413 if self
._BuildDir
== None:
1414 self
._BuildDir
= path
.join(
1415 self
.PlatformInfo
.BuildDir
,
1418 self
.MetaFile
.BaseName
1420 CreateDirectory(self
._BuildDir
)
1421 return self
._BuildDir
1423 ## Return the directory to store the intermediate object files of the mdoule
1424 def _GetOutputDir(self
):
1425 if self
._OutputDir
== None:
1426 self
._OutputDir
= path
.join(self
.BuildDir
, "OUTPUT")
1427 CreateDirectory(self
._OutputDir
)
1428 return self
._OutputDir
1430 ## Return the directory to store auto-gened source files of the mdoule
1431 def _GetDebugDir(self
):
1432 if self
._DebugDir
== None:
1433 self
._DebugDir
= path
.join(self
.BuildDir
, "DEBUG")
1434 CreateDirectory(self
._DebugDir
)
1435 return self
._DebugDir
1437 ## Return the path of custom file
1438 def _GetCustomMakefile(self
):
1439 if self
._CustomMakefile
== None:
1440 self
._CustomMakefile
= {}
1441 for Type
in self
.Module
.CustomMakefile
:
1442 if Type
in gMakeTypeMap
:
1443 MakeType
= gMakeTypeMap
[Type
]
1446 if self
.SourceOverrideDir
!= None:
1447 File
= os
.path
.join(self
.SourceOverrideDir
, self
.Module
.CustomMakefile
[Type
])
1448 if not os
.path
.exists(File
):
1449 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
1451 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
1452 self
._CustomMakefile
[MakeType
] = File
1453 return self
._CustomMakefile
1455 ## Return the directory of the makefile
1457 # @retval string The directory string of module's makefile
1459 def _GetMakeFileDir(self
):
1460 return self
.BuildDir
1462 ## Return build command string
1464 # @retval string Build command string
1466 def _GetBuildCommand(self
):
1467 return self
.PlatformInfo
.BuildCommand
1469 ## Get object list of all packages the module and its dependent libraries belong to
1471 # @retval list The list of package object
1473 def _GetDerivedPackageList(self
):
1475 for M
in [self
.Module
] + self
.DependentLibraryList
:
1476 for Package
in M
.Packages
:
1477 if Package
in PackageList
:
1479 PackageList
.append(Package
)
1482 ## Merge dependency expression
1484 # @retval list The token list of the dependency expression after parsed
1486 def _GetDepexTokenList(self
):
1487 if self
._DepexList
== None:
1488 self
._DepexList
= {}
1489 if self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
1490 return self
._DepexList
1492 self
._DepexList
[self
.ModuleType
] = []
1494 for ModuleType
in self
._DepexList
:
1495 DepexList
= self
._DepexList
[ModuleType
]
1497 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
1499 for M
in [self
.Module
] + self
.DependentLibraryList
:
1501 for D
in M
.Depex
[self
.Arch
, ModuleType
]:
1503 DepexList
.append('AND')
1504 DepexList
.append('(')
1506 if DepexList
[-1] == 'END': # no need of a END at this time
1508 DepexList
.append(')')
1511 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexList
))
1512 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
1514 if len(DepexList
) > 0:
1515 EdkLogger
.verbose('')
1516 return self
._DepexList
1518 ## Merge dependency expression
1520 # @retval list The token list of the dependency expression after parsed
1522 def _GetDepexExpressionTokenList(self
):
1523 if self
._DepexExpressionList
== None:
1524 self
._DepexExpressionList
= {}
1525 if self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
1526 return self
._DepexExpressionList
1528 self
._DepexExpressionList
[self
.ModuleType
] = ''
1530 for ModuleType
in self
._DepexExpressionList
:
1531 DepexExpressionList
= self
._DepexExpressionList
[ModuleType
]
1533 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
1535 for M
in [self
.Module
] + self
.DependentLibraryList
:
1537 for D
in M
.DepexExpression
[self
.Arch
, ModuleType
]:
1538 if DepexExpressionList
!= '':
1539 DepexExpressionList
+= ' AND '
1540 DepexExpressionList
+= '('
1541 DepexExpressionList
+= D
1542 DepexExpressionList
= DepexExpressionList
.rstrip('END').strip()
1543 DepexExpressionList
+= ')'
1546 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexExpressionList
))
1547 if 'BEFORE' in DepexExpressionList
or 'AFTER' in DepexExpressionList
:
1549 if len(DepexExpressionList
) > 0:
1550 EdkLogger
.verbose('')
1551 self
._DepexExpressionList
[ModuleType
] = DepexExpressionList
1552 return self
._DepexExpressionList
1554 ## Return the list of specification version required for the module
1556 # @retval list The list of specification defined in module file
1558 def _GetSpecification(self
):
1559 return self
.Module
.Specification
1561 ## Tool option for the module build
1563 # @param PlatformInfo The object of PlatformBuildInfo
1564 # @retval dict The dict containing valid options
1566 def _GetModuleBuildOption(self
):
1567 if self
._BuildOption
== None:
1568 self
._BuildOption
= self
.PlatformInfo
.ApplyBuildOption(self
.Module
)
1569 return self
._BuildOption
1571 ## Return a list of files which can be built from source
1573 # What kind of files can be built is determined by build rules in
1574 # $(WORKSPACE)/Conf/build_rule.txt and toolchain family.
1576 def _GetSourceFileList(self
):
1577 if self
._SourceFileList
== None:
1578 self
._SourceFileList
= []
1579 for F
in self
.Module
.Sources
:
1581 if F
.TagName
!= "" and F
.TagName
!= self
.ToolChain
:
1582 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "The toolchain [%s] for processing file [%s] is found, "
1583 "but [%s] is needed" % (F
.TagName
, str(F
), self
.ToolChain
))
1585 # match tool chain family
1586 if F
.ToolChainFamily
!= "" and F
.ToolChainFamily
!= self
.ToolChainFamily
:
1589 "The file [%s] must be built by tools of [%s], " \
1590 "but current toolchain family is [%s]" \
1591 % (str(F
), F
.ToolChainFamily
, self
.ToolChainFamily
))
1594 # add the file path into search path list for file including
1595 if F
.Dir
not in self
.IncludePathList
and self
.AutoGenVersion
>= 0x00010005:
1596 self
.IncludePathList
.insert(0, F
.Dir
)
1597 self
._SourceFileList
.append(F
)
1598 self
._ApplyBuildRule
(F
, TAB_UNKNOWN_FILE
)
1599 return self
._SourceFileList
1601 ## Return the list of unicode files
1602 def _GetUnicodeFileList(self
):
1603 if self
._UnicodeFileList
== None:
1604 if TAB_UNICODE_FILE
in self
.FileTypes
:
1605 self
._UnicodeFileList
= self
.FileTypes
[TAB_UNICODE_FILE
]
1607 self
._UnicodeFileList
= []
1608 return self
._UnicodeFileList
1610 ## Return a list of files which can be built from binary
1612 # "Build" binary files are just to copy them to build directory.
1614 # @retval list The list of files which can be built later
1616 def _GetBinaryFiles(self
):
1617 if self
._BinaryFileList
== None:
1618 self
._BinaryFileList
= []
1619 for F
in self
.Module
.Binaries
:
1620 if F
.Target
not in ['COMMON', '*'] and F
.Target
!= self
.BuildTarget
:
1622 self
._BinaryFileList
.append(F
)
1623 self
._ApplyBuildRule
(F
, F
.Type
)
1624 return self
._BinaryFileList
1626 def _GetBuildRules(self
):
1627 if self
._BuildRules
== None:
1629 BuildRuleDatabase
= self
.PlatformInfo
.BuildRule
1630 for Type
in BuildRuleDatabase
.FileTypeList
:
1631 #first try getting build rule by BuildRuleFamily
1632 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.BuildRuleFamily
]
1634 # build type is always module type, but ...
1635 if self
.ModuleType
!= self
.BuildType
:
1636 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.BuildRuleFamily
]
1637 #second try getting build rule by ToolChainFamily
1639 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.ToolChainFamily
]
1641 # build type is always module type, but ...
1642 if self
.ModuleType
!= self
.BuildType
:
1643 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.ToolChainFamily
]
1646 RuleObject
= RuleObject
.Instantiate(self
.Macros
)
1647 BuildRules
[Type
] = RuleObject
1648 for Ext
in RuleObject
.SourceFileExtList
:
1649 BuildRules
[Ext
] = RuleObject
1650 self
._BuildRules
= BuildRules
1651 return self
._BuildRules
1653 def _ApplyBuildRule(self
, File
, FileType
):
1654 if self
._BuildTargets
== None:
1655 self
._IntroBuildTargetList
= set()
1656 self
._FinalBuildTargetList
= set()
1657 self
._BuildTargets
= {}
1658 self
._FileTypes
= {}
1664 while Index
< len(SourceList
):
1665 Source
= SourceList
[Index
]
1669 CreateDirectory(Source
.Dir
)
1671 if File
.IsBinary
and File
== Source
and self
._BinaryFileList
!= None and File
in self
._BinaryFileList
:
1672 RuleObject
= self
.BuildRules
[TAB_DEFAULT_BINARY_FILE
]
1673 elif FileType
in self
.BuildRules
:
1674 RuleObject
= self
.BuildRules
[FileType
]
1675 elif Source
.Ext
in self
.BuildRules
:
1676 RuleObject
= self
.BuildRules
[Source
.Ext
]
1678 # stop at no more rules
1680 self
._FinalBuildTargetList
.add(LastTarget
)
1683 FileType
= RuleObject
.SourceFileType
1684 if FileType
not in self
._FileTypes
:
1685 self
._FileTypes
[FileType
] = set()
1686 self
._FileTypes
[FileType
].add(Source
)
1688 # stop at STATIC_LIBRARY for library
1689 if self
.IsLibrary
and FileType
== TAB_STATIC_LIBRARY
:
1691 self
._FinalBuildTargetList
.add(LastTarget
)
1694 Target
= RuleObject
.Apply(Source
)
1697 self
._FinalBuildTargetList
.add(LastTarget
)
1699 elif not Target
.Outputs
:
1700 # Only do build for target with outputs
1701 self
._FinalBuildTargetList
.add(Target
)
1703 if FileType
not in self
._BuildTargets
:
1704 self
._BuildTargets
[FileType
] = set()
1705 self
._BuildTargets
[FileType
].add(Target
)
1707 if not Source
.IsBinary
and Source
== File
:
1708 self
._IntroBuildTargetList
.add(Target
)
1710 # to avoid cyclic rule
1711 if FileType
in RuleChain
:
1714 RuleChain
.append(FileType
)
1715 SourceList
.extend(Target
.Outputs
)
1717 FileType
= TAB_UNKNOWN_FILE
1719 def _GetTargets(self
):
1720 if self
._BuildTargets
== None:
1721 self
._IntroBuildTargetList
= set()
1722 self
._FinalBuildTargetList
= set()
1723 self
._BuildTargets
= {}
1724 self
._FileTypes
= {}
1726 #TRICK: call _GetSourceFileList to apply build rule for binary files
1727 if self
.SourceFileList
:
1730 #TRICK: call _GetBinaryFileList to apply build rule for binary files
1731 if self
.BinaryFileList
:
1734 return self
._BuildTargets
1736 def _GetIntroTargetList(self
):
1738 return self
._IntroBuildTargetList
1740 def _GetFinalTargetList(self
):
1742 return self
._FinalBuildTargetList
1744 def _GetFileTypes(self
):
1746 return self
._FileTypes
1748 ## Get the list of package object the module depends on
1750 # @retval list The package object list
1752 def _GetDependentPackageList(self
):
1753 return self
.Module
.Packages
1755 ## Return the list of auto-generated code file
1757 # @retval list The list of auto-generated file
1759 def _GetAutoGenFileList(self
):
1760 UniStringAutoGenC
= True
1761 UniStringBinBuffer
= None
1762 if self
.BuildType
== 'UEFI_HII':
1763 UniStringBinBuffer
= StringIO()
1764 UniStringAutoGenC
= False
1765 if self
._AutoGenFileList
== None:
1766 self
._AutoGenFileList
= {}
1767 AutoGenC
= TemplateString()
1768 AutoGenH
= TemplateString()
1769 StringH
= TemplateString()
1770 GenC
.CreateCode(self
, AutoGenC
, AutoGenH
, StringH
, UniStringAutoGenC
, UniStringBinBuffer
)
1771 if str(AutoGenC
) != "" and TAB_C_CODE_FILE
in self
.FileTypes
:
1772 AutoFile
= PathClass(gAutoGenCodeFileName
, self
.DebugDir
)
1773 self
._AutoGenFileList
[AutoFile
] = str(AutoGenC
)
1774 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
1775 if str(AutoGenH
) != "":
1776 AutoFile
= PathClass(gAutoGenHeaderFileName
, self
.DebugDir
)
1777 self
._AutoGenFileList
[AutoFile
] = str(AutoGenH
)
1778 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
1779 if str(StringH
) != "":
1780 AutoFile
= PathClass(gAutoGenStringFileName
% {"module_name":self
.Name
}, self
.DebugDir
)
1781 self
._AutoGenFileList
[AutoFile
] = str(StringH
)
1782 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
1783 if UniStringBinBuffer
!= None and UniStringBinBuffer
.getvalue() != "":
1784 AutoFile
= PathClass(gAutoGenStringFormFileName
% {"module_name":self
.Name
}, self
.OutputDir
)
1785 self
._AutoGenFileList
[AutoFile
] = UniStringBinBuffer
.getvalue()
1786 AutoFile
.IsBinary
= True
1787 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
1788 if UniStringBinBuffer
!= None:
1789 UniStringBinBuffer
.close()
1790 return self
._AutoGenFileList
1792 ## Return the list of library modules explicitly or implicityly used by this module
1793 def _GetLibraryList(self
):
1794 if self
._DependentLibraryList
== None:
1795 # only merge library classes and PCD for non-library module
1797 self
._DependentLibraryList
= []
1799 if self
.AutoGenVersion
< 0x00010005:
1800 self
._DependentLibraryList
= self
.PlatformInfo
.ResolveLibraryReference(self
.Module
)
1802 self
._DependentLibraryList
= self
.PlatformInfo
.ApplyLibraryInstance(self
.Module
)
1803 return self
._DependentLibraryList
1805 ## Get the list of PCDs from current module
1807 # @retval list The list of PCD
1809 def _GetModulePcdList(self
):
1810 if self
._ModulePcdList
== None:
1811 # apply PCD settings from platform
1812 self
._ModulePcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, self
.Module
.Pcds
)
1813 return self
._ModulePcdList
1815 ## Get the list of PCDs from dependent libraries
1817 # @retval list The list of PCD
1819 def _GetLibraryPcdList(self
):
1820 if self
._LibraryPcdList
== None:
1822 if not self
.IsLibrary
:
1823 # get PCDs from dependent libraries
1824 for Library
in self
.DependentLibraryList
:
1825 for Key
in Library
.Pcds
:
1826 # skip duplicated PCDs
1827 if Key
in self
.Module
.Pcds
or Key
in Pcds
:
1829 Pcds
[Key
] = copy
.copy(Library
.Pcds
[Key
])
1830 # apply PCD settings from platform
1831 self
._LibraryPcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, Pcds
)
1833 self
._LibraryPcdList
= []
1834 return self
._LibraryPcdList
1836 ## Get the GUID value mapping
1838 # @retval dict The mapping between GUID cname and its value
1840 def _GetGuidList(self
):
1841 if self
._GuidList
== None:
1842 self
._GuidList
= self
.Module
.Guids
1843 for Library
in self
.DependentLibraryList
:
1844 self
._GuidList
.update(Library
.Guids
)
1845 return self
._GuidList
1847 ## Get the protocol value mapping
1849 # @retval dict The mapping between protocol cname and its value
1851 def _GetProtocolList(self
):
1852 if self
._ProtocolList
== None:
1853 self
._ProtocolList
= self
.Module
.Protocols
1854 for Library
in self
.DependentLibraryList
:
1855 self
._ProtocolList
.update(Library
.Protocols
)
1856 return self
._ProtocolList
1858 ## Get the PPI value mapping
1860 # @retval dict The mapping between PPI cname and its value
1862 def _GetPpiList(self
):
1863 if self
._PpiList
== None:
1864 self
._PpiList
= self
.Module
.Ppis
1865 for Library
in self
.DependentLibraryList
:
1866 self
._PpiList
.update(Library
.Ppis
)
1867 return self
._PpiList
1869 ## Get the list of include search path
1871 # @retval list The list path
1873 def _GetIncludePathList(self
):
1874 if self
._IncludePathList
== None:
1875 self
._IncludePathList
= []
1876 if self
.AutoGenVersion
< 0x00010005:
1877 for Inc
in self
.Module
.Includes
:
1878 if Inc
not in self
._IncludePathList
:
1879 self
._IncludePathList
.append(Inc
)
1881 Inc
= path
.join(Inc
, self
.Arch
.capitalize())
1882 if os
.path
.exists(Inc
) and Inc
not in self
._IncludePathList
:
1883 self
._IncludePathList
.append(Inc
)
1884 # r8 module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
1885 self
._IncludePathList
.append(self
.DebugDir
)
1887 self
._IncludePathList
.append(self
.MetaFile
.Dir
)
1888 self
._IncludePathList
.append(self
.DebugDir
)
1890 for Package
in self
.Module
.Packages
:
1891 PackageDir
= path
.join(self
.WorkspaceDir
, Package
.MetaFile
.Dir
)
1892 if PackageDir
not in self
._IncludePathList
:
1893 self
._IncludePathList
.append(PackageDir
)
1894 for Inc
in Package
.Includes
:
1895 if Inc
not in self
._IncludePathList
:
1896 self
._IncludePathList
.append(str(Inc
))
1897 return self
._IncludePathList
1899 ## Create makefile for the module and its dependent libraries
1901 # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of
1902 # dependent libraries will be created
1904 def CreateMakeFile(self
, CreateLibraryMakeFile
=True):
1905 if self
.IsMakeFileCreated
:
1908 if not self
.IsLibrary
and CreateLibraryMakeFile
:
1909 for LibraryAutoGen
in self
.LibraryAutoGenList
:
1910 LibraryAutoGen
.CreateMakeFile()
1912 if len(self
.CustomMakefile
) == 0:
1913 Makefile
= GenMake
.ModuleMakefile(self
)
1915 Makefile
= GenMake
.CustomMakefile(self
)
1916 if Makefile
.Generate():
1917 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for module %s [%s]" %
1918 (self
.Name
, self
.Arch
))
1920 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for module %s [%s]" %
1921 (self
.Name
, self
.Arch
))
1923 self
.IsMakeFileCreated
= True
1925 ## Create autogen code for the module and its dependent libraries
1927 # @param CreateLibraryCodeFile Flag indicating if or not the code of
1928 # dependent libraries will be created
1930 def CreateCodeFile(self
, CreateLibraryCodeFile
=True):
1931 if self
.IsCodeFileCreated
:
1934 if not self
.IsLibrary
and CreateLibraryCodeFile
:
1935 for LibraryAutoGen
in self
.LibraryAutoGenList
:
1936 LibraryAutoGen
.CreateCodeFile()
1939 IgoredAutoGenList
= []
1941 for File
in self
.AutoGenFileList
:
1942 if GenC
.Generate(File
.Path
, self
.AutoGenFileList
[File
], File
.IsBinary
):
1943 #Ignore R8 AutoGen.c
1944 if self
.AutoGenVersion
< 0x00010005 and File
.Name
== 'AutoGen.c':
1947 AutoGenList
.append(str(File
))
1949 IgoredAutoGenList
.append(str(File
))
1951 # Skip the following code for EDK I inf
1952 if self
.AutoGenVersion
< 0x00010005:
1955 for ModuleType
in self
.DepexList
:
1956 if len(self
.DepexList
[ModuleType
]) == 0:
1958 Dpx
= GenDepex
.DependencyExpression(self
.DepexList
[ModuleType
], ModuleType
, True)
1959 DpxFile
= gAutoGenDepexFileName
% {"module_name" : self
.Name
}
1961 if Dpx
.Generate(path
.join(self
.OutputDir
, DpxFile
)):
1962 AutoGenList
.append(str(DpxFile
))
1964 IgoredAutoGenList
.append(str(DpxFile
))
1966 if IgoredAutoGenList
== []:
1967 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] files for module %s [%s]" %
1968 (" ".join(AutoGenList
), self
.Name
, self
.Arch
))
1969 elif AutoGenList
== []:
1970 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of [%s] files for module %s [%s]" %
1971 (" ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
1973 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] (skipped %s) files for module %s [%s]" %
1974 (" ".join(AutoGenList
), " ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
1976 self
.IsCodeFileCreated
= True
1979 ## Summarize the ModuleAutoGen objects of all libraries used by this module
1980 def _GetLibraryAutoGenList(self
):
1981 if self
._LibraryAutoGenList
== None:
1982 self
._LibraryAutoGenList
= []
1983 for Library
in self
.DependentLibraryList
:
1990 self
.PlatformInfo
.MetaFile
1992 if La
not in self
._LibraryAutoGenList
:
1993 self
._LibraryAutoGenList
.append(La
)
1994 for Lib
in La
.CodaTargetList
:
1995 self
._ApplyBuildRule
(Lib
.Target
, TAB_UNKNOWN_FILE
)
1996 return self
._LibraryAutoGenList
1998 ## Return build command string
2000 # @retval string Build command string
2002 def _GetBuildCommand(self
):
2003 return self
.PlatformInfo
.BuildCommand
2006 Module
= property(_GetModule
)
2007 Name
= property(_GetBaseName
)
2008 Guid
= property(_GetGuid
)
2009 Version
= property(_GetVersion
)
2010 ModuleType
= property(_GetModuleType
)
2011 ComponentType
= property(_GetComponentType
)
2012 BuildType
= property(_GetBuildType
)
2013 PcdIsDriver
= property(_GetPcdIsDriver
)
2014 AutoGenVersion
= property(_GetAutoGenVersion
)
2015 Macros
= property(_GetMacros
)
2016 Specification
= property(_GetSpecification
)
2018 IsLibrary
= property(_IsLibrary
)
2020 BuildDir
= property(_GetBuildDir
)
2021 OutputDir
= property(_GetOutputDir
)
2022 DebugDir
= property(_GetDebugDir
)
2023 MakeFileDir
= property(_GetMakeFileDir
)
2024 CustomMakefile
= property(_GetCustomMakefile
)
2026 IncludePathList
= property(_GetIncludePathList
)
2027 AutoGenFileList
= property(_GetAutoGenFileList
)
2028 UnicodeFileList
= property(_GetUnicodeFileList
)
2029 SourceFileList
= property(_GetSourceFileList
)
2030 BinaryFileList
= property(_GetBinaryFiles
) # FileType : [File List]
2031 Targets
= property(_GetTargets
)
2032 IntroTargetList
= property(_GetIntroTargetList
)
2033 CodaTargetList
= property(_GetFinalTargetList
)
2034 FileTypes
= property(_GetFileTypes
)
2035 BuildRules
= property(_GetBuildRules
)
2037 DependentPackageList
= property(_GetDependentPackageList
)
2038 DependentLibraryList
= property(_GetLibraryList
)
2039 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
2040 DerivedPackageList
= property(_GetDerivedPackageList
)
2042 ModulePcdList
= property(_GetModulePcdList
)
2043 LibraryPcdList
= property(_GetLibraryPcdList
)
2044 GuidList
= property(_GetGuidList
)
2045 ProtocolList
= property(_GetProtocolList
)
2046 PpiList
= property(_GetPpiList
)
2047 DepexList
= property(_GetDepexTokenList
)
2048 DepexExpressionList
= property(_GetDepexExpressionTokenList
)
2049 BuildOption
= property(_GetModuleBuildOption
)
2050 BuildCommand
= property(_GetBuildCommand
)
2052 # This acts like the main() function for the script, unless it is 'import'ed into another script.
2053 if __name__
== '__main__':