2 # Generate AutoGen.h, AutoGen.c and *.depex files
4 # Copyright (c) 2007 - 2009, Intel Corporation
5 # All rights reserved. This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 import os
.path
as path
25 from StrGather
import *
26 from BuildEngine
import BuildRule
28 from Common
.BuildToolError
import *
29 from Common
.DataType
import *
30 from Common
.Misc
import *
31 from Common
.String
import *
32 import Common
.GlobalData
as GlobalData
33 from GenFds
.FdfParser
import *
34 from CommonDataClass
.CommonClass
import SkuInfoClass
35 from Workspace
.BuildClassObject
import *
37 ## Regular expression for splitting Dependency Expression stirng into tokens
38 gDepexTokenPattern
= re
.compile("(\(|\)|\w+| \S+\.inf)")
40 ## Mapping Makefile type
41 gMakeTypeMap
= {"MSFT":"nmake", "GCC":"gmake"}
44 ## Build rule configuration file
45 gBuildRuleFile
= 'Conf/build_rule.txt'
47 ## default file name for AutoGen
48 gAutoGenCodeFileName
= "AutoGen.c"
49 gAutoGenHeaderFileName
= "AutoGen.h"
50 gAutoGenStringFileName
= "%(module_name)sStrDefs.h"
51 gAutoGenDepexFileName
= "%(module_name)s.depex"
52 gAutoGenSmmDepexFileName
= "%(module_name)s.smm"
54 ## Base class for AutoGen
56 # This class just implements the cache mechanism of AutoGen objects.
58 class AutoGen(object):
59 # database to maintain the objects of xxxAutoGen
60 _CACHE_
= {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}
64 # @param Class class object of real AutoGen class
65 # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
66 # @param Workspace Workspace directory or WorkspaceAutoGen object
67 # @param MetaFile The path of meta file
68 # @param Target Build target
69 # @param Toolchain Tool chain name
70 # @param Arch Target arch
71 # @param *args The specific class related parameters
72 # @param **kwargs The specific class related dict parameters
74 def __new__(Class
, Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
75 # check if the object has been created
76 Key
= (Target
, Toolchain
)
77 if Key
not in Class
._CACHE
_ or Arch
not in Class
._CACHE
_[Key
] \
78 or MetaFile
not in Class
._CACHE
_[Key
][Arch
]:
79 AutoGenObject
= super(AutoGen
, Class
).__new
__(Class
)
80 # call real constructor
81 if not AutoGenObject
._Init
(Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
83 if Key
not in Class
._CACHE
_:
84 Class
._CACHE
_[Key
] = {}
85 if Arch
not in Class
._CACHE
_[Key
]:
86 Class
._CACHE
_[Key
][Arch
] = {}
87 Class
._CACHE
_[Key
][Arch
][MetaFile
] = AutoGenObject
89 AutoGenObject
= Class
._CACHE
_[Key
][Arch
][MetaFile
]
95 # The file path of platform file will be used to represent hash value of this object
97 # @retval int Hash value of the file path of platform file
100 return hash(self
.MetaFile
)
104 # The file path of platform file will be used to represent this object
106 # @retval string String of platform file path
109 return str(self
.MetaFile
)
112 def __eq__(self
, Other
):
113 return Other
and self
.MetaFile
== Other
115 ## Workspace AutoGen class
117 # This class is used mainly to control the whole platform build for different
118 # architecture. This class will generate top level makefile.
120 class WorkspaceAutoGen(AutoGen
):
121 ## Real constructor of WorkspaceAutoGen
123 # This method behaves the same as __init__ except that it needs explict invoke
124 # (in super class's __new__ method)
126 # @param WorkspaceDir Root directory of workspace
127 # @param ActivePlatform Meta-file of active platform
128 # @param Target Build target
129 # @param Toolchain Tool chain name
130 # @param ArchList List of architecture of current build
131 # @param MetaFileDb Database containing meta-files
132 # @param BuildConfig Configuration of build
133 # @param ToolDefinition Tool chain definitions
134 # @param FlashDefinitionFile File of flash definition
135 # @param Fds FD list to be generated
136 # @param Fvs FV list to be generated
137 # @param SkuId SKU id from command line
139 def _Init(self
, WorkspaceDir
, ActivePlatform
, Target
, Toolchain
, ArchList
, MetaFileDb
,
140 BuildConfig
, ToolDefinition
, FlashDefinitionFile
='', Fds
=[], Fvs
=[], SkuId
=''):
141 self
.MetaFile
= ActivePlatform
.MetaFile
142 self
.WorkspaceDir
= WorkspaceDir
143 self
.Platform
= ActivePlatform
144 self
.BuildTarget
= Target
145 self
.ToolChain
= Toolchain
146 self
.ArchList
= ArchList
149 self
.BuildDatabase
= MetaFileDb
150 self
.TargetTxt
= BuildConfig
151 self
.ToolDef
= ToolDefinition
152 self
.FdfFile
= FlashDefinitionFile
153 self
.FdTargetList
= Fds
154 self
.FvTargetList
= Fvs
155 self
.AutoGenObjectList
= []
157 # there's many relative directory operations, so ...
158 os
.chdir(self
.WorkspaceDir
)
160 # parse FDF file to get PCDs in it, if any
161 if self
.FdfFile
!= None and self
.FdfFile
!= '':
162 Fdf
= FdfParser(self
.FdfFile
.Path
)
164 PcdSet
= Fdf
.Profile
.PcdDict
165 ModuleList
= Fdf
.Profile
.InfList
170 # apply SKU and inject PCDs from Flash Definition file
171 for Arch
in self
.ArchList
:
172 Platform
= self
.BuildDatabase
[self
.MetaFile
, Arch
]
173 Platform
.SkuName
= self
.SkuId
174 for Name
, Guid
in PcdSet
:
175 Platform
.AddPcd(Name
, Guid
, PcdSet
[Name
, Guid
])
177 Pa
= PlatformAutoGen(self
, self
.MetaFile
, Target
, Toolchain
, Arch
)
179 # Explicitly collect platform's dynamic PCDs
181 Pa
.CollectPlatformDynamicPcds()
182 self
.AutoGenObjectList
.append(Pa
)
184 self
._BuildDir
= None
186 self
._MakeFileDir
= None
187 self
._BuildCommand
= None
192 return "%s [%s]" % (self
.MetaFile
, ", ".join(self
.ArchList
))
194 ## Return the directory to store FV files
196 if self
._FvDir
== None:
197 self
._FvDir
= path
.join(self
.BuildDir
, 'FV')
200 ## Return the directory to store all intermediate and final files built
201 def _GetBuildDir(self
):
202 return self
.AutoGenObjectList
[0].BuildDir
204 ## Return the build output directory platform specifies
205 def _GetOutputDir(self
):
206 return self
.Platform
.OutputDirectory
208 ## Return platform name
210 return self
.Platform
.PlatformName
212 ## Return meta-file GUID
214 return self
.Platform
.Guid
216 ## Return platform version
217 def _GetVersion(self
):
218 return self
.Platform
.Version
220 ## Return paths of tools
221 def _GetToolDefinition(self
):
222 return self
.AutoGenObjectList
[0].ToolDefinition
224 ## Return directory of platform makefile
226 # @retval string Makefile directory
228 def _GetMakeFileDir(self
):
229 if self
._MakeFileDir
== None:
230 self
._MakeFileDir
= self
.BuildDir
231 return self
._MakeFileDir
233 ## Return build command string
235 # @retval string Build command string
237 def _GetBuildCommand(self
):
238 if self
._BuildCommand
== None:
239 # BuildCommand should be all the same. So just get one from platform AutoGen
240 self
._BuildCommand
= self
.AutoGenObjectList
[0].BuildCommand
241 return self
._BuildCommand
243 ## Create makefile for the platform and mdoules in it
245 # @param CreateDepsMakeFile Flag indicating if the makefile for
246 # modules will be created as well
248 def CreateMakeFile(self
, CreateDepsMakeFile
=False):
249 # create makefile for platform
250 Makefile
= GenMake
.TopLevelMakefile(self
)
251 if Makefile
.Generate():
252 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for platform [%s] %s\n" %
253 (self
.MetaFile
, self
.ArchList
))
255 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for platform [%s] %s\n" %
256 (self
.MetaFile
, self
.ArchList
))
258 if CreateDepsMakeFile
:
259 for Pa
in self
.AutoGenObjectList
:
260 Pa
.CreateMakeFile(CreateDepsMakeFile
)
262 ## Create autogen code for platform and modules
264 # Since there's no autogen code for platform, this method will do nothing
265 # if CreateModuleCodeFile is set to False.
267 # @param CreateDepsCodeFile Flag indicating if creating module's
268 # autogen code file or not
270 def CreateCodeFile(self
, CreateDepsCodeFile
=False):
271 if not CreateDepsCodeFile
:
273 for Pa
in self
.AutoGenObjectList
:
274 Pa
.CreateCodeFile(CreateDepsCodeFile
)
276 Name
= property(_GetName
)
277 Guid
= property(_GetGuid
)
278 Version
= property(_GetVersion
)
279 OutputDir
= property(_GetOutputDir
)
281 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
283 BuildDir
= property(_GetBuildDir
)
284 FvDir
= property(_GetFvDir
)
285 MakeFileDir
= property(_GetMakeFileDir
)
286 BuildCommand
= property(_GetBuildCommand
)
288 ## AutoGen class for platform
290 # PlatformAutoGen class will process the original information in platform
291 # file in order to generate makefile for platform.
293 class PlatformAutoGen(AutoGen
):
295 # Used to store all PCDs for both PEI and DXE phase, in order to generate
296 # correct PCD database
299 _NonDynaPcdList_
= []
301 ## The real constructor of PlatformAutoGen
303 # This method is not supposed to be called by users of PlatformAutoGen. It's
304 # only used by factory method __new__() to do real initialization work for an
305 # object of PlatformAutoGen
307 # @param Workspace WorkspaceAutoGen object
308 # @param PlatformFile Platform file (DSC file)
309 # @param Target Build target (DEBUG, RELEASE)
310 # @param Toolchain Name of tool chain
311 # @param Arch arch of the platform supports
313 def _Init(self
, Workspace
, PlatformFile
, Target
, Toolchain
, Arch
):
314 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen platform [%s] [%s]" % (PlatformFile
, Arch
))
315 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (PlatformFile
, Arch
, Toolchain
, Target
)
317 self
.MetaFile
= PlatformFile
318 self
.Workspace
= Workspace
319 self
.WorkspaceDir
= Workspace
.WorkspaceDir
320 self
.ToolChain
= Toolchain
321 self
.BuildTarget
= Target
323 self
.SourceDir
= PlatformFile
.SubDir
324 self
.SourceOverrideDir
= None
325 self
.FdTargetList
= self
.Workspace
.FdTargetList
326 self
.FvTargetList
= self
.Workspace
.FvTargetList
328 # flag indicating if the makefile/C-code file has been created or not
329 self
.IsMakeFileCreated
= False
330 self
.IsCodeFileCreated
= False
332 self
._Platform
= None
337 self
._BuildRule
= None
338 self
._SourceDir
= None
339 self
._BuildDir
= None
340 self
._OutputDir
= None
342 self
._MakeFileDir
= None
345 self
._PcdTokenNumber
= None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
346 self
._DynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
347 self
._NonDynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
349 self
._ToolDefinitions
= None
350 self
._ToolDefFile
= None # toolcode : tool path
351 self
._ToolChainFamily
= None
352 self
._BuildRuleFamily
= None
353 self
._BuildOption
= None # toolcode : option
354 self
._PackageList
= None
355 self
._ModuleAutoGenList
= None
356 self
._LibraryAutoGenList
= None
357 self
._BuildCommand
= None
359 # get the original module/package/platform objects
360 self
.BuildDatabase
= Workspace
.BuildDatabase
364 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
366 ## Create autogen code for platform and modules
368 # Since there's no autogen code for platform, this method will do nothing
369 # if CreateModuleCodeFile is set to False.
371 # @param CreateModuleCodeFile Flag indicating if creating module's
372 # autogen code file or not
374 def CreateCodeFile(self
, CreateModuleCodeFile
=False):
375 # only module has code to be greated, so do nothing if CreateModuleCodeFile is False
376 if self
.IsCodeFileCreated
or not CreateModuleCodeFile
:
379 for Ma
in self
.ModuleAutoGenList
:
380 Ma
.CreateCodeFile(True)
382 # don't do this twice
383 self
.IsCodeFileCreated
= True
385 ## Create makefile for the platform and mdoules in it
387 # @param CreateModuleMakeFile Flag indicating if the makefile for
388 # modules will be created as well
390 def CreateMakeFile(self
, CreateModuleMakeFile
=False):
391 if CreateModuleMakeFile
:
392 for ModuleFile
in self
.Platform
.Modules
:
393 Ma
= ModuleAutoGen(self
.Workspace
, ModuleFile
, self
.BuildTarget
,
394 self
.ToolChain
, self
.Arch
, self
.MetaFile
)
395 Ma
.CreateMakeFile(True)
397 # no need to create makefile for the platform more than once
398 if self
.IsMakeFileCreated
:
401 # create makefile for platform
402 Makefile
= GenMake
.PlatformMakefile(self
)
403 if Makefile
.Generate():
404 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for platform [%s] [%s]\n" %
405 (self
.MetaFile
, self
.Arch
))
407 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for platform [%s] [%s]\n" %
408 (self
.MetaFile
, self
.Arch
))
409 self
.IsMakeFileCreated
= True
411 ## Collect dynamic PCDs
413 # Gather dynamic PCDs list from each module and their settings from platform
414 # This interface should be invoked explicitly when platform action is created.
416 def CollectPlatformDynamicPcds(self
):
417 # for gathering error information
418 NoDatumTypePcdList
= set()
421 for F
in self
.Platform
.Modules
.keys():
422 M
= ModuleAutoGen(self
.Workspace
, F
, self
.BuildTarget
, self
.ToolChain
, self
.Arch
, self
.MetaFile
)
423 #GuidValue.update(M.Guids)
424 for PcdFromModule
in M
.ModulePcdList
+M
.LibraryPcdList
:
425 # make sure that the "VOID*" kind of datum has MaxDatumSize set
426 if PcdFromModule
.DatumType
== "VOID*" and PcdFromModule
.MaxDatumSize
== None:
427 NoDatumTypePcdList
.add("%s.%s [%s]" % (PcdFromModule
.TokenSpaceGuidCName
, PcdFromModule
.TokenCName
, F
))
429 if PcdFromModule
.Type
in GenC
.gDynamicPcd
or PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
431 # If a dynamic PCD used by a PEM module/PEI module & DXE module,
432 # it should be stored in Pcd PEI database, If a dynamic only
433 # used by DXE module, it should be stored in DXE PCD database.
434 # The default Phase is DXE
436 if M
.ModuleType
in ["PEIM", "PEI_CORE"]:
437 PcdFromModule
.Phase
= "PEI"
438 if PcdFromModule
not in self
._DynaPcdList
_:
439 self
._DynaPcdList
_.append(PcdFromModule
)
440 elif PcdFromModule
.Phase
== 'PEI':
441 # overwrite any the same PCD existing, if Phase is PEI
442 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
443 self
._DynaPcdList
_[Index
] = PcdFromModule
444 elif PcdFromModule
not in self
._NonDynaPcdList
_:
445 self
._NonDynaPcdList
_.append(PcdFromModule
)
447 # print out error information and break the build, if error found
448 if len(NoDatumTypePcdList
) > 0:
449 NoDatumTypePcdListString
= "\n\t\t".join(NoDatumTypePcdList
)
450 EdkLogger
.error("build", AUTOGEN_ERROR
, "PCD setting error",
452 ExtraData
="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
453 % NoDatumTypePcdListString
)
454 self
._NonDynamicPcdList
= self
._NonDynaPcdList
_
455 self
._DynamicPcdList
= self
._DynaPcdList
_
458 # Sort dynamic PCD list to:
459 # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should
460 # try to be put header of dynamicd List
461 # 2) If PCD is HII type, the PCD item should be put after unicode type PCD
463 # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.
468 for Pcd
in self
._DynamicPcdList
:
469 # just pick the a value to determine whether is unicode string type
470 Sku
= Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]]
471 PcdValue
= Sku
.DefaultValue
472 if Pcd
.DatumType
== 'VOID*' and PcdValue
.startswith("L"):
473 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
474 UnicodePcdArray
.append(Pcd
)
475 elif len(Sku
.VariableName
) > 0:
476 # if found HII type PCD then insert to right of UnicodeIndex
477 HiiPcdArray
.append(Pcd
)
479 OtherPcdArray
.append(Pcd
)
480 del self
._DynamicPcdList
[:]
481 self
._DynamicPcdList
.extend(UnicodePcdArray
)
482 self
._DynamicPcdList
.extend(HiiPcdArray
)
483 self
._DynamicPcdList
.extend(OtherPcdArray
)
486 ## Return the platform build data object
487 def _GetPlatform(self
):
488 if self
._Platform
== None:
489 self
._Platform
= self
.BuildDatabase
[self
.MetaFile
, self
.Arch
]
490 return self
._Platform
492 ## Return platform name
494 return self
.Platform
.PlatformName
496 ## Return the meta file GUID
498 return self
.Platform
.Guid
500 ## Return the platform version
501 def _GetVersion(self
):
502 return self
.Platform
.Version
504 ## Return the FDF file name
505 def _GetFdfFile(self
):
506 if self
._FdfFile
== None:
507 if self
.Workspace
.FdfFile
!= "":
508 self
._FdfFile
= path
.join(self
.WorkspaceDir
, self
.Workspace
.FdfFile
)
513 ## Return the build output directory platform specifies
514 def _GetOutputDir(self
):
515 return self
.Platform
.OutputDirectory
517 ## Return the directory to store all intermediate and final files built
518 def _GetBuildDir(self
):
519 if self
._BuildDir
== None:
520 if os
.path
.isabs(self
.OutputDir
):
521 self
._BuildDir
= path
.join(
522 path
.abspath(self
.OutputDir
),
523 self
.BuildTarget
+ "_" + self
.ToolChain
,
526 self
._BuildDir
= path
.join(
529 self
.BuildTarget
+ "_" + self
.ToolChain
,
531 return self
._BuildDir
533 ## Return directory of platform makefile
535 # @retval string Makefile directory
537 def _GetMakeFileDir(self
):
538 if self
._MakeFileDir
== None:
539 self
._MakeFileDir
= path
.join(self
.BuildDir
, self
.Arch
)
540 return self
._MakeFileDir
542 ## Return build command string
544 # @retval string Build command string
546 def _GetBuildCommand(self
):
547 if self
._BuildCommand
== None:
548 self
._BuildCommand
= []
549 if "MAKE" in self
.ToolDefinition
and "PATH" in self
.ToolDefinition
["MAKE"]:
550 self
._BuildCommand
+= SplitOption(self
.ToolDefinition
["MAKE"]["PATH"])
551 if "FLAGS" in self
.ToolDefinition
["MAKE"]:
552 NewOption
= self
.ToolDefinition
["MAKE"]["FLAGS"].strip()
554 self
._BuildCommand
+= SplitOption(NewOption
)
555 return self
._BuildCommand
557 ## Get tool chain definition
559 # Get each tool defition for given tool chain from tools_def.txt and platform
561 def _GetToolDefinition(self
):
562 if self
._ToolDefinitions
== None:
563 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDictionary
564 if TAB_TOD_DEFINES_COMMAND_TYPE
not in self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
:
565 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No tools found in configuration",
566 ExtraData
="[%s]" % self
.MetaFile
)
567 self
._ToolDefinitions
= {}
569 for Def
in ToolDefinition
:
570 Target
, Tag
, Arch
, Tool
, Attr
= Def
.split("_")
571 if Target
!= self
.BuildTarget
or Tag
!= self
.ToolChain
or Arch
!= self
.Arch
:
574 Value
= ToolDefinition
[Def
]
575 # don't record the DLL
577 DllPathList
.add(Value
)
580 if Tool
not in self
._ToolDefinitions
:
581 self
._ToolDefinitions
[Tool
] = {}
582 self
._ToolDefinitions
[Tool
][Attr
] = Value
586 if GlobalData
.gOptions
.SilentMode
and "MAKE" in self
._ToolDefinitions
:
587 if "FLAGS" not in self
._ToolDefinitions
["MAKE"]:
588 self
._ToolDefinitions
["MAKE"]["FLAGS"] = ""
589 self
._ToolDefinitions
["MAKE"]["FLAGS"] += " -s"
591 for Tool
in self
._ToolDefinitions
:
592 for Attr
in self
._ToolDefinitions
[Tool
]:
593 Value
= self
._ToolDefinitions
[Tool
][Attr
]
594 if Tool
in self
.BuildOption
and Attr
in self
.BuildOption
[Tool
]:
595 # check if override is indicated
596 if self
.BuildOption
[Tool
][Attr
].startswith('='):
597 Value
= self
.BuildOption
[Tool
][Attr
][1:]
599 Value
+= " " + self
.BuildOption
[Tool
][Attr
]
602 # Don't put MAKE definition in the file
606 ToolsDef
+= "%s = %s\n" % (Tool
, Value
)
608 # Don't put MAKE definition in the file
613 ToolsDef
+= "%s_%s = %s\n" % (Tool
, Attr
, Value
)
616 SaveFileOnChange(self
.ToolDefinitionFile
, ToolsDef
)
617 for DllPath
in DllPathList
:
618 os
.environ
["PATH"] = DllPath
+ os
.pathsep
+ os
.environ
["PATH"]
619 os
.environ
["MAKE_FLAGS"] = MakeFlags
621 return self
._ToolDefinitions
623 ## Return the paths of tools
624 def _GetToolDefFile(self
):
625 if self
._ToolDefFile
== None:
626 self
._ToolDefFile
= os
.path
.join(self
.MakeFileDir
, "TOOLS_DEF." + self
.Arch
)
627 return self
._ToolDefFile
629 ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.
630 def _GetToolChainFamily(self
):
631 if self
._ToolChainFamily
== None:
632 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
633 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
634 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
635 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]:
636 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
638 self
._ToolChainFamily
= "MSFT"
640 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]
641 return self
._ToolChainFamily
643 def _GetBuildRuleFamily(self
):
644 if self
._BuildRuleFamily
== None:
645 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
646 if TAB_TOD_DEFINES_BUILDRULEFAMILY
not in ToolDefinition \
647 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
] \
648 or not ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]:
649 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
651 self
._BuildRuleFamily
= "MSFT"
653 self
._BuildRuleFamily
= ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]
654 return self
._BuildRuleFamily
656 ## Return the build options specific to this platform
657 def _GetBuildOptions(self
):
658 if self
._BuildOption
== None:
659 self
._BuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
)
660 return self
._BuildOption
662 ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt
664 # @retval BuildRule object
666 def _GetBuildRule(self
):
667 if self
._BuildRule
== None:
669 if TAB_TAT_DEFINES_BUILD_RULE_CONF
in self
.Workspace
.TargetTxt
.TargetTxtDictionary
:
670 BuildRuleFile
= self
.Workspace
.TargetTxt
.TargetTxtDictionary
[TAB_TAT_DEFINES_BUILD_RULE_CONF
]
671 if BuildRuleFile
in [None, '']:
672 BuildRuleFile
= gBuildRuleFile
673 self
._BuildRule
= BuildRule(BuildRuleFile
)
674 return self
._BuildRule
676 ## Summarize the packages used by modules in this platform
677 def _GetPackageList(self
):
678 if self
._PackageList
== None:
679 self
._PackageList
= set()
680 for La
in self
.LibraryAutoGenList
:
681 self
._PackageList
.update(La
.DependentPackageList
)
682 for Ma
in self
.ModuleAutoGenList
:
683 self
._PackageList
.update(Ma
.DependentPackageList
)
684 self
._PackageList
= list(self
._PackageList
)
685 return self
._PackageList
687 ## Get list of non-dynamic PCDs
688 def _GetNonDynamicPcdList(self
):
689 return self
._NonDynamicPcdList
691 ## Get list of dynamic PCDs
692 def _GetDynamicPcdList(self
):
693 return self
._DynamicPcdList
695 ## Generate Token Number for all PCD
696 def _GetPcdTokenNumbers(self
):
697 if self
._PcdTokenNumber
== None:
698 self
._PcdTokenNumber
= sdict()
700 for Pcd
in self
.DynamicPcdList
:
701 if Pcd
.Phase
== "PEI":
702 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
703 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
706 for Pcd
in self
.DynamicPcdList
:
707 if Pcd
.Phase
== "DXE":
708 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
709 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
712 for Pcd
in self
.NonDynamicPcdList
:
713 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
715 return self
._PcdTokenNumber
717 ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform
718 def _GetAutoGenObjectList(self
):
719 self
._ModuleAutoGenList
= []
720 self
._LibraryAutoGenList
= []
721 for ModuleFile
in self
.Platform
.Modules
:
730 if Ma
not in self
._ModuleAutoGenList
:
731 self
._ModuleAutoGenList
.append(Ma
)
732 for La
in Ma
.LibraryAutoGenList
:
733 if La
not in self
._LibraryAutoGenList
:
734 self
._LibraryAutoGenList
.append(La
)
736 ## Summarize ModuleAutoGen objects of all modules to be built for this platform
737 def _GetModuleAutoGenList(self
):
738 if self
._ModuleAutoGenList
== None:
739 self
._GetAutoGenObjectList
()
740 return self
._ModuleAutoGenList
742 ## Summarize ModuleAutoGen objects of all libraries to be built for this platform
743 def _GetLibraryAutoGenList(self
):
744 if self
._LibraryAutoGenList
== None:
745 self
._GetAutoGenObjectList
()
746 return self
._LibraryAutoGenList
748 ## Test if a module is supported by the platform
750 # An error will be raised directly if the module or its arch is not supported
751 # by the platform or current configuration
753 def ValidModule(self
, Module
):
754 return Module
in self
.Platform
.Modules
or Module
in self
.Platform
.LibraryInstances
756 ## Resolve the library classes in a module to library instances
758 # This method will not only resolve library classes but also sort the library
759 # instances according to the dependency-ship.
761 # @param Module The module from which the library classes will be resolved
763 # @retval library_list List of library instances sorted
765 def ApplyLibraryInstance(self
, Module
):
766 ModuleType
= Module
.ModuleType
768 # for overridding library instances with module specific setting
769 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
771 # add forced library instance
772 for LibraryClass
in PlatformModule
.LibraryClasses
:
773 if LibraryClass
.startswith("NULL"):
774 Module
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
777 LibraryConsumerList
= [Module
]
779 ConsumedByList
= sdict()
780 LibraryInstance
= sdict()
782 EdkLogger
.verbose("")
783 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
784 while len(LibraryConsumerList
) > 0:
785 M
= LibraryConsumerList
.pop()
786 for LibraryClassName
in M
.LibraryClasses
:
787 if LibraryClassName
not in LibraryInstance
:
788 # override library instance for this module
789 if LibraryClassName
in PlatformModule
.LibraryClasses
:
790 LibraryPath
= PlatformModule
.LibraryClasses
[LibraryClassName
]
792 LibraryPath
= self
.Platform
.LibraryClasses
[LibraryClassName
, ModuleType
]
793 if LibraryPath
== None or LibraryPath
== "":
794 LibraryPath
= M
.LibraryClasses
[LibraryClassName
]
795 if LibraryPath
== None or LibraryPath
== "":
796 EdkLogger
.error("build", RESOURCE_NOT_AVAILABLE
,
797 "Instance of library class [%s] is not found" % LibraryClassName
,
799 ExtraData
="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M
), self
.Arch
, str(Module
)))
801 LibraryModule
= self
.BuildDatabase
[LibraryPath
, self
.Arch
]
802 # for those forced library instance (NULL library), add a fake library class
803 if LibraryClassName
.startswith("NULL"):
804 LibraryModule
.LibraryClass
.append(LibraryClassObject(LibraryClassName
, [ModuleType
]))
805 elif LibraryModule
.LibraryClass
== None \
806 or len(LibraryModule
.LibraryClass
) == 0 \
807 or (ModuleType
!= 'USER_DEFINED'
808 and ModuleType
not in LibraryModule
.LibraryClass
[0].SupModList
):
809 # only USER_DEFINED can link against any library instance despite of its SupModList
810 EdkLogger
.error("build", OPTION_MISSING
,
811 "Module type [%s] is not supported by library instance [%s]" \
812 % (ModuleType
, LibraryPath
), File
=self
.MetaFile
,
813 ExtraData
="consumed by [%s]" % str(Module
))
815 LibraryInstance
[LibraryClassName
] = LibraryModule
816 LibraryConsumerList
.append(LibraryModule
)
817 EdkLogger
.verbose("\t" + str(LibraryClassName
) + " : " + str(LibraryModule
))
819 LibraryModule
= LibraryInstance
[LibraryClassName
]
821 if LibraryModule
== None:
824 if LibraryModule
.ConstructorList
!= [] and LibraryModule
not in Constructor
:
825 Constructor
.append(LibraryModule
)
827 if LibraryModule
not in ConsumedByList
:
828 ConsumedByList
[LibraryModule
] = []
829 # don't add current module itself to consumer list
831 if M
in ConsumedByList
[LibraryModule
]:
833 ConsumedByList
[LibraryModule
].append(M
)
835 # Initialize the sorted output list to the empty set
837 SortedLibraryList
= []
839 # Q <- Set of all nodes with no incoming edges
841 LibraryList
= [] #LibraryInstance.values()
843 for LibraryClassName
in LibraryInstance
:
844 M
= LibraryInstance
[LibraryClassName
]
845 LibraryList
.append(M
)
846 if ConsumedByList
[M
] == []:
850 # start the DAG algorithm
854 while Q
== [] and EdgeRemoved
:
856 # for each node Item with a Constructor
857 for Item
in LibraryList
:
858 if Item
not in Constructor
:
860 # for each Node without a constructor with an edge e from Item to Node
861 for Node
in ConsumedByList
[Item
]:
862 if Node
in Constructor
:
864 # remove edge e from the graph if Node has no constructor
865 ConsumedByList
[Item
].remove(Node
)
867 if ConsumedByList
[Item
] == []:
873 # DAG is done if there's no more incoming edge for all nodes
880 SortedLibraryList
.append(Node
)
882 # for each node Item with an edge e from Node to Item do
883 for Item
in LibraryList
:
884 if Node
not in ConsumedByList
[Item
]:
886 # remove edge e from the graph
887 ConsumedByList
[Item
].remove(Node
)
889 if ConsumedByList
[Item
] != []:
891 # insert Item into Q, if Item has no other incoming edges
895 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
897 for Item
in LibraryList
:
898 if ConsumedByList
[Item
] != [] and Item
in Constructor
and len(Constructor
) > 1:
899 ErrorMessage
= "\tconsumed by " + "\n\tconsumed by ".join([str(L
) for L
in ConsumedByList
[Item
]])
900 EdkLogger
.error("build", BUILD_ERROR
, 'Library [%s] with constructors has a cycle' % str(Item
),
901 ExtraData
=ErrorMessage
, File
=self
.MetaFile
)
902 if Item
not in SortedLibraryList
:
903 SortedLibraryList
.append(Item
)
906 # Build the list of constructor and destructir names
907 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
909 SortedLibraryList
.reverse()
910 return SortedLibraryList
913 ## Override PCD setting (type, value, ...)
915 # @param ToPcd The PCD to be overrided
916 # @param FromPcd The PCD overrideing from
918 def _OverridePcd(self
, ToPcd
, FromPcd
, Module
=""):
920 # in case there's PCDs coming from FDF file, which have no type given.
921 # at this point, ToPcd.Type has the type found from dependent
925 if ToPcd
.Pending
and FromPcd
.Type
not in [None, '']:
926 ToPcd
.Type
= FromPcd
.Type
927 elif ToPcd
.Type
not in [None, ''] and FromPcd
.Type
not in [None, ''] \
928 and ToPcd
.Type
!= FromPcd
.Type
:
929 EdkLogger
.error("build", OPTION_CONFLICT
, "Mismatched PCD type",
930 ExtraData
="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
931 % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
,
932 ToPcd
.Type
, Module
, FromPcd
.Type
),
935 if FromPcd
.MaxDatumSize
not in [None, '']:
936 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
937 if FromPcd
.DefaultValue
not in [None, '']:
938 ToPcd
.DefaultValue
= FromPcd
.DefaultValue
939 if FromPcd
.TokenValue
not in [None, '']:
940 ToPcd
.TokenValue
= FromPcd
.TokenValue
941 if FromPcd
.MaxDatumSize
not in [None, '']:
942 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
943 if FromPcd
.DatumType
not in [None, '']:
944 ToPcd
.DatumType
= FromPcd
.DatumType
945 if FromPcd
.SkuInfoList
not in [None, '', []]:
946 ToPcd
.SkuInfoList
= FromPcd
.SkuInfoList
948 # check the validation of datum
949 IsValid
, Cause
= CheckPcdDatum(ToPcd
.DatumType
, ToPcd
.DefaultValue
)
951 EdkLogger
.error('build', FORMAT_INVALID
, Cause
, File
=self
.MetaFile
,
952 ExtraData
="%s.%s" % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
))
954 if ToPcd
.DatumType
== "VOID*" and ToPcd
.MaxDatumSize
in ['', None]:
955 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "No MaxDatumSize specified for PCD %s.%s" \
956 % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
))
957 Value
= ToPcd
.DefaultValue
958 if Value
in [None, '']:
959 ToPcd
.MaxDatumSize
= 1
960 elif Value
[0] == 'L':
961 ToPcd
.MaxDatumSize
= str(len(Value
) * 2)
962 elif Value
[0] == '{':
963 ToPcd
.MaxDatumSize
= str(len(Value
.split(',')))
965 ToPcd
.MaxDatumSize
= str(len(Value
))
967 # apply default SKU for dynamic PCDS if specified one is not available
968 if (ToPcd
.Type
in PCD_DYNAMIC_TYPE_LIST
or ToPcd
.Type
in PCD_DYNAMIC_EX_TYPE_LIST
) \
969 and ToPcd
.SkuInfoList
in [None, {}, '']:
970 if self
.Platform
.SkuName
in self
.Platform
.SkuIds
:
971 SkuName
= self
.Platform
.SkuName
974 ToPcd
.SkuInfoList
= {
975 SkuName
: SkuInfoClass(SkuName
, self
.Platform
.SkuIds
[SkuName
], '', '', '', '', '', ToPcd
.DefaultValue
)
978 ## Apply PCD setting defined platform to a module
980 # @param Module The module from which the PCD setting will be overrided
982 # @retval PCD_list The list PCDs with settings from platform
984 def ApplyPcdSetting(self
, Module
, Pcds
):
985 # for each PCD in module
986 for Name
,Guid
in Pcds
:
987 PcdInModule
= Pcds
[Name
,Guid
]
988 # find out the PCD setting in platform
989 if (Name
,Guid
) in self
.Platform
.Pcds
:
990 PcdInPlatform
= self
.Platform
.Pcds
[Name
,Guid
]
993 # then override the settings if any
994 self
._OverridePcd
(PcdInModule
, PcdInPlatform
, Module
)
995 # resolve the VariableGuid value
996 for SkuId
in PcdInModule
.SkuInfoList
:
997 Sku
= PcdInModule
.SkuInfoList
[SkuId
]
998 if Sku
.VariableGuid
== '': continue
999 Sku
.VariableGuidValue
= GuidValue(Sku
.VariableGuid
, self
.PackageList
)
1000 if Sku
.VariableGuidValue
== None:
1001 PackageList
= "\n\t".join([str(P
) for P
in self
.PackageList
])
1004 RESOURCE_NOT_AVAILABLE
,
1005 "Value of GUID [%s] is not found in" % Sku
.VariableGuid
,
1006 ExtraData
=PackageList
+ "\n\t(used with %s.%s from module %s)" \
1007 % (Guid
, Name
, str(Module
)),
1011 # override PCD settings with module specific setting
1012 if Module
in self
.Platform
.Modules
:
1013 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1014 for Key
in PlatformModule
.Pcds
:
1016 self
._OverridePcd
(Pcds
[Key
], PlatformModule
.Pcds
[Key
], Module
)
1017 return Pcds
.values()
1019 ## Resolve library names to library modules
1021 # (for R8.x modules)
1023 # @param Module The module from which the library names will be resolved
1025 # @retval library_list The list of library modules
1027 def ResolveLibraryReference(self
, Module
):
1028 EdkLogger
.verbose("")
1029 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
1030 LibraryConsumerList
= [Module
]
1032 # "CompilerStub" is a must for R8 modules
1033 if Module
.Libraries
:
1034 Module
.Libraries
.append("CompilerStub")
1036 while len(LibraryConsumerList
) > 0:
1037 M
= LibraryConsumerList
.pop()
1038 for LibraryName
in M
.Libraries
:
1039 Library
= self
.Platform
.LibraryClasses
[LibraryName
, ':dummy:']
1041 for Key
in self
.Platform
.LibraryClasses
.data
.keys():
1042 if LibraryName
.upper() == Key
.upper():
1043 Library
= self
.Platform
.LibraryClasses
[Key
, ':dummy:']
1046 EdkLogger
.warn("build", "Library [%s] is not found" % LibraryName
, File
=str(M
),
1047 ExtraData
="\t%s [%s]" % (str(Module
), self
.Arch
))
1050 if Library
not in LibraryList
:
1051 LibraryList
.append(Library
)
1052 LibraryConsumerList
.append(Library
)
1053 EdkLogger
.verbose("\t" + LibraryName
+ " : " + str(Library
) + ' ' + str(type(Library
)))
1056 ## Expand * in build option key
1058 # @param Options Options to be expanded
1060 # @retval options Options expanded
1062 def _ExpandBuildOption(self
, Options
):
1068 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
1069 # if tool chain family doesn't match, skip it
1070 if Tool
in self
.ToolDefinition
and Family
!= "":
1071 FamilyIsNull
= False
1072 if self
.ToolDefinition
[Tool
].get(TAB_TOD_DEFINES_BUILDRULEFAMILY
, "") != "":
1073 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_BUILDRULEFAMILY
]:
1075 elif Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
1078 # expand any wildcard
1079 if Target
== "*" or Target
== self
.BuildTarget
:
1080 if Tag
== "*" or Tag
== self
.ToolChain
:
1081 if Arch
== "*" or Arch
== self
.Arch
:
1082 if Tool
not in BuildOptions
:
1083 BuildOptions
[Tool
] = {}
1084 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
]:
1085 BuildOptions
[Tool
][Attr
] = Options
[Key
]
1087 # append options for the same tool
1088 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
1089 # Build Option Family has been checked, which need't to be checked again for family.
1090 if FamilyMatch
or FamilyIsNull
:
1095 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
1096 # if tool chain family doesn't match, skip it
1097 if Tool
not in self
.ToolDefinition
or Family
=="":
1099 # option has been added before
1100 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
1103 # expand any wildcard
1104 if Target
== "*" or Target
== self
.BuildTarget
:
1105 if Tag
== "*" or Tag
== self
.ToolChain
:
1106 if Arch
== "*" or Arch
== self
.Arch
:
1107 if Tool
not in BuildOptions
:
1108 BuildOptions
[Tool
] = {}
1109 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
]:
1110 BuildOptions
[Tool
][Attr
] = Options
[Key
]
1112 # append options for the same tool
1113 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
1116 ## Append build options in platform to a module
1118 # @param Module The module to which the build options will be appened
1120 # @retval options The options appended with build options in platform
1122 def ApplyBuildOption(self
, Module
):
1123 PlatformOptions
= self
.BuildOption
1124 ModuleOptions
= self
._ExpandBuildOption
(Module
.BuildOptions
)
1125 if Module
in self
.Platform
.Modules
:
1126 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1127 PlatformModuleOptions
= self
._ExpandBuildOption
(PlatformModule
.BuildOptions
)
1129 PlatformModuleOptions
= {}
1131 AllTools
= set(ModuleOptions
.keys() + PlatformOptions
.keys() + PlatformModuleOptions
.keys() + self
.ToolDefinition
.keys())
1133 for Tool
in AllTools
:
1134 if Tool
not in BuildOptions
:
1135 BuildOptions
[Tool
] = {}
1137 for Options
in [self
.ToolDefinition
, ModuleOptions
, PlatformOptions
, PlatformModuleOptions
]:
1138 if Tool
not in Options
:
1140 for Attr
in Options
[Tool
]:
1141 Value
= Options
[Tool
][Attr
]
1142 if Attr
not in BuildOptions
[Tool
]:
1143 BuildOptions
[Tool
][Attr
] = ""
1144 # check if override is indicated
1145 if Value
.startswith('='):
1146 BuildOptions
[Tool
][Attr
] = Value
[1:]
1148 BuildOptions
[Tool
][Attr
] += " " + Value
1151 Platform
= property(_GetPlatform
)
1152 Name
= property(_GetName
)
1153 Guid
= property(_GetGuid
)
1154 Version
= property(_GetVersion
)
1156 OutputDir
= property(_GetOutputDir
)
1157 BuildDir
= property(_GetBuildDir
)
1158 MakeFileDir
= property(_GetMakeFileDir
)
1159 FdfFile
= property(_GetFdfFile
)
1161 PcdTokenNumber
= property(_GetPcdTokenNumbers
) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
1162 DynamicPcdList
= property(_GetDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1163 NonDynamicPcdList
= property(_GetNonDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1164 PackageList
= property(_GetPackageList
)
1166 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
1167 ToolDefinitionFile
= property(_GetToolDefFile
) # toolcode : lib path
1168 ToolChainFamily
= property(_GetToolChainFamily
)
1169 BuildRuleFamily
= property(_GetBuildRuleFamily
)
1170 BuildOption
= property(_GetBuildOptions
) # toolcode : option
1172 BuildCommand
= property(_GetBuildCommand
)
1173 BuildRule
= property(_GetBuildRule
)
1174 ModuleAutoGenList
= property(_GetModuleAutoGenList
)
1175 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
1177 ## ModuleAutoGen class
1179 # This class encapsules the AutoGen behaviors for the build tools. In addition to
1180 # the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according
1181 # to the [depex] section in module's inf file.
1183 class ModuleAutoGen(AutoGen
):
1184 ## The real constructor of ModuleAutoGen
1186 # This method is not supposed to be called by users of ModuleAutoGen. It's
1187 # only used by factory method __new__() to do real initialization work for an
1188 # object of ModuleAutoGen
1190 # @param Workspace EdkIIWorkspaceBuild object
1191 # @param ModuleFile The path of module file
1192 # @param Target Build target (DEBUG, RELEASE)
1193 # @param Toolchain Name of tool chain
1194 # @param Arch The arch the module supports
1195 # @param PlatformFile Platform meta-file
1197 def _Init(self
, Workspace
, ModuleFile
, Target
, Toolchain
, Arch
, PlatformFile
):
1198 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen module [%s] [%s]" % (ModuleFile
, Arch
))
1199 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (ModuleFile
, Arch
, Toolchain
, Target
)
1201 self
.Workspace
= Workspace
1202 self
.WorkspaceDir
= Workspace
.WorkspaceDir
1204 self
.MetaFile
= ModuleFile
1205 self
.PlatformInfo
= PlatformAutoGen(Workspace
, PlatformFile
, Target
, Toolchain
, Arch
)
1206 # check if this module is employed by active platform
1207 if not self
.PlatformInfo
.ValidModule(self
.MetaFile
):
1208 EdkLogger
.verbose("Module [%s] for [%s] is not employed by active platform\n" \
1209 % (self
.MetaFile
, Arch
))
1212 self
.SourceDir
= self
.MetaFile
.SubDir
1213 self
.SourceOverrideDir
= None
1214 # use overrided path defined in DSC file
1215 if self
.MetaFile
.Key
in GlobalData
.gOverrideDir
:
1216 self
.SourceOverrideDir
= GlobalData
.gOverrideDir
[self
.MetaFile
.Key
]
1218 self
.ToolChain
= Toolchain
1219 self
.BuildTarget
= Target
1221 self
.ToolChainFamily
= self
.PlatformInfo
.ToolChainFamily
1222 self
.BuildRuleFamily
= self
.PlatformInfo
.BuildRuleFamily
1224 self
.IsMakeFileCreated
= False
1225 self
.IsCodeFileCreated
= False
1227 self
.BuildDatabase
= self
.Workspace
.BuildDatabase
1232 self
._Version
= None
1233 self
._ModuleType
= None
1234 self
._ComponentType
= None
1235 self
._PcdIsDriver
= None
1236 self
._AutoGenVersion
= None
1237 self
._LibraryFlag
= None
1238 self
._CustomMakefile
= None
1241 self
._BuildDir
= None
1242 self
._OutputDir
= None
1243 self
._DebugDir
= None
1244 self
._MakeFileDir
= None
1246 self
._IncludePathList
= None
1247 self
._AutoGenFileList
= None
1248 self
._UnicodeFileList
= None
1249 self
._SourceFileList
= None
1250 self
._ObjectFileList
= None
1251 self
._BinaryFileList
= None
1253 self
._DependentPackageList
= None
1254 self
._DependentLibraryList
= None
1255 self
._LibraryAutoGenList
= None
1256 self
._DerivedPackageList
= None
1257 self
._ModulePcdList
= None
1258 self
._LibraryPcdList
= None
1259 self
._GuidList
= None
1260 self
._ProtocolList
= None
1261 self
._PpiList
= None
1262 self
._DepexList
= None
1263 self
._BuildOption
= None
1264 self
._BuildTargets
= None
1265 self
._IntroBuildTargetList
= None
1266 self
._FinalBuildTargetList
= None
1267 self
._FileTypes
= None
1268 self
._BuildRules
= None
1273 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
1275 # Macros could be used in build_rule.txt (also Makefile)
1276 def _GetMacros(self
):
1277 if self
._Macro
== None:
1278 self
._Macro
= sdict()
1279 self
._Macro
["WORKSPACE" ] = self
.WorkspaceDir
1280 self
._Macro
["MODULE_NAME" ] = self
.Name
1281 self
._Macro
["MODULE_GUID" ] = self
.Guid
1282 self
._Macro
["MODULE_VERSION" ] = self
.Version
1283 self
._Macro
["MODULE_TYPE" ] = self
.ModuleType
1284 self
._Macro
["MODULE_FILE" ] = str(self
.MetaFile
)
1285 self
._Macro
["MODULE_FILE_BASE_NAME" ] = self
.MetaFile
.BaseName
1286 self
._Macro
["MODULE_RELATIVE_DIR" ] = self
.SourceDir
1287 self
._Macro
["MODULE_DIR" ] = self
.SourceDir
1289 self
._Macro
["BASE_NAME" ] = self
.Name
1291 self
._Macro
["ARCH" ] = self
.Arch
1292 self
._Macro
["TOOLCHAIN" ] = self
.ToolChain
1293 self
._Macro
["TOOLCHAIN_TAG" ] = self
.ToolChain
1294 self
._Macro
["TARGET" ] = self
.BuildTarget
1296 self
._Macro
["BUILD_DIR" ] = self
.PlatformInfo
.BuildDir
1297 self
._Macro
["BIN_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
1298 self
._Macro
["LIB_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
1299 self
._Macro
["MODULE_BUILD_DIR" ] = self
.BuildDir
1300 self
._Macro
["OUTPUT_DIR" ] = self
.OutputDir
1301 self
._Macro
["DEBUG_DIR" ] = self
.DebugDir
1304 ## Return the module build data object
1305 def _GetModule(self
):
1306 if self
._Module
== None:
1307 self
._Module
= self
.Workspace
.BuildDatabase
[self
.MetaFile
, self
.Arch
]
1310 ## Return the module name
1311 def _GetBaseName(self
):
1312 return self
.Module
.BaseName
1314 ## Return the module SourceOverridePath
1315 def _GetSourceOverridePath(self
):
1316 return self
.Module
.SourceOverridePath
1318 ## Return the module meta-file GUID
1320 return self
.Module
.Guid
1322 ## Return the module version
1323 def _GetVersion(self
):
1324 return self
.Module
.Version
1326 ## Return the module type
1327 def _GetModuleType(self
):
1328 return self
.Module
.ModuleType
1330 ## Return the component type (for R8.x style of module)
1331 def _GetComponentType(self
):
1332 return self
.Module
.ComponentType
1334 ## Return the build type
1335 def _GetBuildType(self
):
1336 return self
.Module
.BuildType
1338 ## Return the PCD_IS_DRIVER setting
1339 def _GetPcdIsDriver(self
):
1340 return self
.Module
.PcdIsDriver
1342 ## Return the autogen version, i.e. module meta-file version
1343 def _GetAutoGenVersion(self
):
1344 return self
.Module
.AutoGenVersion
1346 ## Check if the module is library or not
1347 def _IsLibrary(self
):
1348 if self
._LibraryFlag
== None:
1349 if self
.Module
.LibraryClass
!= None and self
.Module
.LibraryClass
!= []:
1350 self
._LibraryFlag
= True
1352 self
._LibraryFlag
= False
1353 return self
._LibraryFlag
1355 ## Return the directory to store intermediate files of the module
1356 def _GetBuildDir(self
):
1357 if self
._BuildDir
== None:
1358 self
._BuildDir
= path
.join(
1359 self
.PlatformInfo
.BuildDir
,
1362 self
.MetaFile
.BaseName
1364 CreateDirectory(self
._BuildDir
)
1365 return self
._BuildDir
1367 ## Return the directory to store the intermediate object files of the mdoule
1368 def _GetOutputDir(self
):
1369 if self
._OutputDir
== None:
1370 self
._OutputDir
= path
.join(self
.BuildDir
, "OUTPUT")
1371 CreateDirectory(self
._OutputDir
)
1372 return self
._OutputDir
1374 ## Return the directory to store auto-gened source files of the mdoule
1375 def _GetDebugDir(self
):
1376 if self
._DebugDir
== None:
1377 self
._DebugDir
= path
.join(self
.BuildDir
, "DEBUG")
1378 CreateDirectory(self
._DebugDir
)
1379 return self
._DebugDir
1381 ## Return the path of custom file
1382 def _GetCustomMakefile(self
):
1383 if self
._CustomMakefile
== None:
1384 self
._CustomMakefile
= {}
1385 for Type
in self
.Module
.CustomMakefile
:
1386 if Type
in gMakeTypeMap
:
1387 MakeType
= gMakeTypeMap
[Type
]
1390 if self
.SourceOverrideDir
!= None:
1391 File
= os
.path
.join(self
.SourceOverrideDir
, self
.Module
.CustomMakefile
[Type
])
1392 if not os
.path
.exists(File
):
1393 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
1395 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
1396 self
._CustomMakefile
[MakeType
] = File
1397 return self
._CustomMakefile
1399 ## Return the directory of the makefile
1401 # @retval string The directory string of module's makefile
1403 def _GetMakeFileDir(self
):
1404 return self
.BuildDir
1406 ## Return build command string
1408 # @retval string Build command string
1410 def _GetBuildCommand(self
):
1411 return self
.PlatformInfo
.BuildCommand
1413 ## Get object list of all packages the module and its dependent libraries belong to
1415 # @retval list The list of package object
1417 def _GetDerivedPackageList(self
):
1419 for M
in [self
.Module
] + self
.DependentLibraryList
:
1420 for Package
in M
.Packages
:
1421 if Package
in PackageList
:
1423 PackageList
.append(Package
)
1426 ## Merge dependency expression
1428 # @retval list The token list of the dependency expression after parsed
1430 def _GetDepexTokenList(self
):
1431 if self
._DepexList
== None:
1432 self
._DepexList
= {}
1433 if self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
1434 return self
._DepexList
1436 if self
.ModuleType
== "DXE_SMM_DRIVER":
1437 self
._DepexList
["DXE_DRIVER"] = []
1438 self
._DepexList
["SMM_DRIVER"] = []
1440 self
._DepexList
[self
.ModuleType
] = []
1442 for ModuleType
in self
._DepexList
:
1443 DepexList
= self
._DepexList
[ModuleType
]
1445 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
1447 for M
in [self
.Module
] + self
.DependentLibraryList
:
1449 for D
in M
.Depex
[self
.Arch
, ModuleType
]:
1451 DepexList
.append('AND')
1452 DepexList
.append('(')
1454 if DepexList
[-1] == 'END': # no need of a END at this time
1456 DepexList
.append(')')
1459 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexList
))
1460 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
1462 if len(DepexList
) > 0:
1463 EdkLogger
.verbose('')
1464 return self
._DepexList
1466 ## Return the list of specification version required for the module
1468 # @retval list The list of specification defined in module file
1470 def _GetSpecification(self
):
1471 return self
.Module
.Specification
1473 ## Tool option for the module build
1475 # @param PlatformInfo The object of PlatformBuildInfo
1476 # @retval dict The dict containing valid options
1478 def _GetModuleBuildOption(self
):
1479 if self
._BuildOption
== None:
1480 self
._BuildOption
= self
.PlatformInfo
.ApplyBuildOption(self
.Module
)
1481 return self
._BuildOption
1483 ## Return a list of files which can be built from source
1485 # What kind of files can be built is determined by build rules in
1486 # $(WORKSPACE)/Conf/build_rule.txt and toolchain family.
1488 def _GetSourceFileList(self
):
1489 if self
._SourceFileList
== None:
1490 self
._SourceFileList
= []
1491 for F
in self
.Module
.Sources
:
1493 if F
.TagName
!= "" and F
.TagName
!= self
.ToolChain
:
1494 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "The toolchain [%s] for processing file [%s] is found, "
1495 "but [%s] is needed" % (F
.TagName
, str(F
), self
.ToolChain
))
1497 # match tool chain family
1498 if F
.ToolChainFamily
!= "" and F
.ToolChainFamily
!= self
.ToolChainFamily
:
1501 "The file [%s] must be built by tools of [%s], " \
1502 "but current toolchain family is [%s]" \
1503 % (str(F
), F
.ToolChainFamily
, self
.ToolChainFamily
))
1506 # add the file path into search path list for file including
1507 if F
.Dir
not in self
.IncludePathList
and self
.AutoGenVersion
>= 0x00010005:
1508 self
.IncludePathList
.insert(0, F
.Dir
)
1509 self
._SourceFileList
.append(F
)
1510 self
._ApplyBuildRule
(F
, TAB_UNKNOWN_FILE
)
1511 return self
._SourceFileList
1513 ## Return the list of unicode files
1514 def _GetUnicodeFileList(self
):
1515 if self
._UnicodeFileList
== None:
1516 if TAB_UNICODE_FILE
in self
.FileTypes
:
1517 self
._UnicodeFileList
= self
.FileTypes
[TAB_UNICODE_FILE
]
1519 self
._UnicodeFileList
= []
1520 return self
._UnicodeFileList
1522 ## Return a list of files which can be built from binary
1524 # "Build" binary files are just to copy them to build directory.
1526 # @retval list The list of files which can be built later
1528 def _GetBinaryFiles(self
):
1529 if self
._BinaryFileList
== None:
1530 self
._BinaryFileList
= []
1531 for F
in self
.Module
.Binaries
:
1532 if F
.Target
not in ['COMMON', '*'] and F
.Target
!= self
.BuildTarget
:
1534 self
._BinaryFileList
.append(F
)
1535 self
._ApplyBuildRule
(F
, F
.Type
)
1536 return self
._BinaryFileList
1538 def _GetBuildRules(self
):
1539 if self
._BuildRules
== None:
1541 BuildRuleDatabase
= self
.PlatformInfo
.BuildRule
1542 for Type
in BuildRuleDatabase
.FileTypeList
:
1543 #first try getting build rule by BuildRuleFamily
1544 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.BuildRuleFamily
]
1546 # build type is always module type, but ...
1547 if self
.ModuleType
!= self
.BuildType
:
1548 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.BuildRuleFamily
]
1549 #second try getting build rule by ToolChainFamily
1551 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.ToolChainFamily
]
1553 # build type is always module type, but ...
1554 if self
.ModuleType
!= self
.BuildType
:
1555 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.ToolChainFamily
]
1558 RuleObject
= RuleObject
.Instantiate(self
.Macros
)
1559 BuildRules
[Type
] = RuleObject
1560 for Ext
in RuleObject
.SourceFileExtList
:
1561 BuildRules
[Ext
] = RuleObject
1562 self
._BuildRules
= BuildRules
1563 return self
._BuildRules
1565 def _ApplyBuildRule(self
, File
, FileType
):
1566 if self
._BuildTargets
== None:
1567 self
._IntroBuildTargetList
= set()
1568 self
._FinalBuildTargetList
= set()
1569 self
._BuildTargets
= {}
1570 self
._FileTypes
= {}
1576 while Index
< len(SourceList
):
1577 Source
= SourceList
[Index
]
1581 CreateDirectory(Source
.Dir
)
1583 if FileType
in self
.BuildRules
:
1584 RuleObject
= self
.BuildRules
[FileType
]
1585 elif Source
.Ext
in self
.BuildRules
:
1586 RuleObject
= self
.BuildRules
[Source
.Ext
]
1587 elif File
.IsBinary
and File
== Source
:
1588 RuleObject
= self
.BuildRules
[TAB_DEFAULT_BINARY_FILE
]
1590 # stop at no more rules
1592 self
._FinalBuildTargetList
.add(LastTarget
)
1595 FileType
= RuleObject
.SourceFileType
1596 if FileType
not in self
._FileTypes
:
1597 self
._FileTypes
[FileType
] = set()
1598 self
._FileTypes
[FileType
].add(Source
)
1600 # stop at STATIC_LIBRARY for library
1601 if self
.IsLibrary
and FileType
== TAB_STATIC_LIBRARY
:
1602 self
._FinalBuildTargetList
.add(LastTarget
)
1605 Target
= RuleObject
.Apply(Source
)
1608 self
._FinalBuildTargetList
.add(LastTarget
)
1610 elif not Target
.Outputs
:
1611 # Only do build for target with outputs
1612 self
._FinalBuildTargetList
.add(Target
)
1614 if FileType
not in self
._BuildTargets
:
1615 self
._BuildTargets
[FileType
] = set()
1616 self
._BuildTargets
[FileType
].add(Target
)
1618 if not Source
.IsBinary
and Source
== File
:
1619 self
._IntroBuildTargetList
.add(Target
)
1621 # to avoid cyclic rule
1622 if FileType
in RuleChain
:
1625 RuleChain
.append(FileType
)
1626 SourceList
.extend(Target
.Outputs
)
1628 FileType
= TAB_UNKNOWN_FILE
1630 def _GetTargets(self
):
1631 if self
._BuildTargets
== None:
1632 self
._IntroBuildTargetList
= set()
1633 self
._FinalBuildTargetList
= set()
1634 self
._BuildTargets
= {}
1635 self
._FileTypes
= {}
1637 #TRICK: call _GetSourceFileList to apply build rule for binary files
1638 if self
.SourceFileList
:
1641 #TRICK: call _GetBinaryFileList to apply build rule for binary files
1642 if self
.BinaryFileList
:
1645 return self
._BuildTargets
1647 def _GetIntroTargetList(self
):
1649 return self
._IntroBuildTargetList
1651 def _GetFinalTargetList(self
):
1653 return self
._FinalBuildTargetList
1655 def _GetFileTypes(self
):
1657 return self
._FileTypes
1659 ## Get the list of package object the module depends on
1661 # @retval list The package object list
1663 def _GetDependentPackageList(self
):
1664 return self
.Module
.Packages
1666 ## Return the list of auto-generated code file
1668 # @retval list The list of auto-generated file
1670 def _GetAutoGenFileList(self
):
1671 if self
._AutoGenFileList
== None:
1672 self
._AutoGenFileList
= {}
1673 AutoGenC
= TemplateString()
1674 AutoGenH
= TemplateString()
1675 StringH
= TemplateString()
1676 GenC
.CreateCode(self
, AutoGenC
, AutoGenH
, StringH
)
1677 if str(AutoGenC
) != "" and TAB_C_CODE_FILE
in self
.FileTypes
:
1678 AutoFile
= PathClass(gAutoGenCodeFileName
, self
.DebugDir
)
1679 self
._AutoGenFileList
[AutoFile
] = str(AutoGenC
)
1680 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
1681 if str(AutoGenH
) != "":
1682 AutoFile
= PathClass(gAutoGenHeaderFileName
, self
.DebugDir
)
1683 self
._AutoGenFileList
[AutoFile
] = str(AutoGenH
)
1684 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
1685 if str(StringH
) != "":
1686 AutoFile
= PathClass(gAutoGenStringFileName
% {"module_name":self
.Name
}, self
.DebugDir
)
1687 self
._AutoGenFileList
[AutoFile
] = str(StringH
)
1688 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
1689 return self
._AutoGenFileList
1691 ## Return the list of library modules explicitly or implicityly used by this module
1692 def _GetLibraryList(self
):
1693 if self
._DependentLibraryList
== None:
1694 # only merge library classes and PCD for non-library module
1696 self
._DependentLibraryList
= []
1698 if self
.AutoGenVersion
< 0x00010005:
1699 self
._DependentLibraryList
= self
.PlatformInfo
.ResolveLibraryReference(self
.Module
)
1701 self
._DependentLibraryList
= self
.PlatformInfo
.ApplyLibraryInstance(self
.Module
)
1702 return self
._DependentLibraryList
1704 ## Get the list of PCDs from current module
1706 # @retval list The list of PCD
1708 def _GetModulePcdList(self
):
1709 if self
._ModulePcdList
== None:
1710 # apply PCD settings from platform
1711 self
._ModulePcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, self
.Module
.Pcds
)
1712 return self
._ModulePcdList
1714 ## Get the list of PCDs from dependent libraries
1716 # @retval list The list of PCD
1718 def _GetLibraryPcdList(self
):
1719 if self
._LibraryPcdList
== None:
1721 if not self
.IsLibrary
:
1722 # get PCDs from dependent libraries
1723 for Library
in self
.DependentLibraryList
:
1724 for Key
in Library
.Pcds
:
1725 # skip duplicated PCDs
1726 if Key
in self
.Module
.Pcds
or Key
in Pcds
:
1728 Pcds
[Key
] = copy
.copy(Library
.Pcds
[Key
])
1729 # apply PCD settings from platform
1730 self
._LibraryPcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, Pcds
)
1732 self
._LibraryPcdList
= []
1733 return self
._LibraryPcdList
1735 ## Get the GUID value mapping
1737 # @retval dict The mapping between GUID cname and its value
1739 def _GetGuidList(self
):
1740 if self
._GuidList
== None:
1741 self
._GuidList
= self
.Module
.Guids
1742 for Library
in self
.DependentLibraryList
:
1743 self
._GuidList
.update(Library
.Guids
)
1744 return self
._GuidList
1746 ## Get the protocol value mapping
1748 # @retval dict The mapping between protocol cname and its value
1750 def _GetProtocolList(self
):
1751 if self
._ProtocolList
== None:
1752 self
._ProtocolList
= self
.Module
.Protocols
1753 for Library
in self
.DependentLibraryList
:
1754 self
._ProtocolList
.update(Library
.Protocols
)
1755 return self
._ProtocolList
1757 ## Get the PPI value mapping
1759 # @retval dict The mapping between PPI cname and its value
1761 def _GetPpiList(self
):
1762 if self
._PpiList
== None:
1763 self
._PpiList
= self
.Module
.Ppis
1764 for Library
in self
.DependentLibraryList
:
1765 self
._PpiList
.update(Library
.Ppis
)
1766 return self
._PpiList
1768 ## Get the list of include search path
1770 # @retval list The list path
1772 def _GetIncludePathList(self
):
1773 if self
._IncludePathList
== None:
1774 self
._IncludePathList
= []
1775 if self
.AutoGenVersion
< 0x00010005:
1776 for Inc
in self
.Module
.Includes
:
1777 if Inc
not in self
._IncludePathList
:
1778 self
._IncludePathList
.append(Inc
)
1780 Inc
= path
.join(Inc
, self
.Arch
.capitalize())
1781 if os
.path
.exists(Inc
) and Inc
not in self
._IncludePathList
:
1782 self
._IncludePathList
.append(Inc
)
1783 # r8 module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
1784 self
._IncludePathList
.append(self
.DebugDir
)
1786 self
._IncludePathList
.append(self
.MetaFile
.Dir
)
1787 self
._IncludePathList
.append(self
.DebugDir
)
1789 for Package
in self
.Module
.Packages
:
1790 PackageDir
= path
.join(self
.WorkspaceDir
, Package
.MetaFile
.Dir
)
1791 if PackageDir
not in self
._IncludePathList
:
1792 self
._IncludePathList
.append(PackageDir
)
1793 for Inc
in Package
.Includes
:
1794 if Inc
not in self
._IncludePathList
:
1795 self
._IncludePathList
.append(str(Inc
))
1796 return self
._IncludePathList
1798 ## Create makefile for the module and its dependent libraries
1800 # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of
1801 # dependent libraries will be created
1803 def CreateMakeFile(self
, CreateLibraryMakeFile
=True):
1804 if self
.IsMakeFileCreated
:
1807 if not self
.IsLibrary
and CreateLibraryMakeFile
:
1808 for LibraryAutoGen
in self
.LibraryAutoGenList
:
1809 LibraryAutoGen
.CreateMakeFile()
1811 if len(self
.CustomMakefile
) == 0:
1812 Makefile
= GenMake
.ModuleMakefile(self
)
1814 Makefile
= GenMake
.CustomMakefile(self
)
1815 if Makefile
.Generate():
1816 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for module %s [%s]" %
1817 (self
.Name
, self
.Arch
))
1819 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for module %s [%s]" %
1820 (self
.Name
, self
.Arch
))
1822 self
.IsMakeFileCreated
= True
1824 ## Create autogen code for the module and its dependent libraries
1826 # @param CreateLibraryCodeFile Flag indicating if or not the code of
1827 # dependent libraries will be created
1829 def CreateCodeFile(self
, CreateLibraryCodeFile
=True):
1830 if self
.IsCodeFileCreated
:
1833 if not self
.IsLibrary
and CreateLibraryCodeFile
:
1834 for LibraryAutoGen
in self
.LibraryAutoGenList
:
1835 LibraryAutoGen
.CreateCodeFile()
1838 IgoredAutoGenList
= []
1840 for File
in self
.AutoGenFileList
:
1841 if GenC
.Generate(File
.Path
, self
.AutoGenFileList
[File
]):
1842 #Ignore R8 AutoGen.c
1843 if self
.AutoGenVersion
< 0x00010005 and File
.Name
== 'AutoGen.c':
1846 AutoGenList
.append(str(File
))
1848 IgoredAutoGenList
.append(str(File
))
1850 # Skip the following code for EDK I inf
1851 if self
.AutoGenVersion
< 0x00010005:
1854 for ModuleType
in self
.DepexList
:
1855 if len(self
.DepexList
[ModuleType
]) == 0:
1857 Dpx
= GenDepex
.DependencyExpression(self
.DepexList
[ModuleType
], ModuleType
, True)
1858 if ModuleType
== 'SMM_DRIVER':
1859 DpxFile
= gAutoGenSmmDepexFileName
% {"module_name" : self
.Name
}
1861 DpxFile
= gAutoGenDepexFileName
% {"module_name" : self
.Name
}
1863 if Dpx
.Generate(path
.join(self
.OutputDir
, DpxFile
)):
1864 AutoGenList
.append(str(DpxFile
))
1866 IgoredAutoGenList
.append(str(DpxFile
))
1868 if IgoredAutoGenList
== []:
1869 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] files for module %s [%s]" %
1870 (" ".join(AutoGenList
), self
.Name
, self
.Arch
))
1871 elif AutoGenList
== []:
1872 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of [%s] files for module %s [%s]" %
1873 (" ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
1875 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] (skipped %s) files for module %s [%s]" %
1876 (" ".join(AutoGenList
), " ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
1878 self
.IsCodeFileCreated
= True
1881 ## Summarize the ModuleAutoGen objects of all libraries used by this module
1882 def _GetLibraryAutoGenList(self
):
1883 if self
._LibraryAutoGenList
== None:
1884 self
._LibraryAutoGenList
= []
1885 for Library
in self
.DependentLibraryList
:
1892 self
.PlatformInfo
.MetaFile
1894 if La
not in self
._LibraryAutoGenList
:
1895 self
._LibraryAutoGenList
.append(La
)
1896 for Lib
in La
.CodaTargetList
:
1897 self
._ApplyBuildRule
(Lib
.Target
, TAB_UNKNOWN_FILE
)
1898 return self
._LibraryAutoGenList
1900 ## Return build command string
1902 # @retval string Build command string
1904 def _GetBuildCommand(self
):
1905 return self
.PlatformInfo
.BuildCommand
1908 Module
= property(_GetModule
)
1909 Name
= property(_GetBaseName
)
1910 Guid
= property(_GetGuid
)
1911 Version
= property(_GetVersion
)
1912 ModuleType
= property(_GetModuleType
)
1913 ComponentType
= property(_GetComponentType
)
1914 BuildType
= property(_GetBuildType
)
1915 PcdIsDriver
= property(_GetPcdIsDriver
)
1916 AutoGenVersion
= property(_GetAutoGenVersion
)
1917 Macros
= property(_GetMacros
)
1918 Specification
= property(_GetSpecification
)
1920 IsLibrary
= property(_IsLibrary
)
1922 BuildDir
= property(_GetBuildDir
)
1923 OutputDir
= property(_GetOutputDir
)
1924 DebugDir
= property(_GetDebugDir
)
1925 MakeFileDir
= property(_GetMakeFileDir
)
1926 CustomMakefile
= property(_GetCustomMakefile
)
1928 IncludePathList
= property(_GetIncludePathList
)
1929 AutoGenFileList
= property(_GetAutoGenFileList
)
1930 UnicodeFileList
= property(_GetUnicodeFileList
)
1931 SourceFileList
= property(_GetSourceFileList
)
1932 BinaryFileList
= property(_GetBinaryFiles
) # FileType : [File List]
1933 Targets
= property(_GetTargets
)
1934 IntroTargetList
= property(_GetIntroTargetList
)
1935 CodaTargetList
= property(_GetFinalTargetList
)
1936 FileTypes
= property(_GetFileTypes
)
1937 BuildRules
= property(_GetBuildRules
)
1939 DependentPackageList
= property(_GetDependentPackageList
)
1940 DependentLibraryList
= property(_GetLibraryList
)
1941 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
1942 DerivedPackageList
= property(_GetDerivedPackageList
)
1944 ModulePcdList
= property(_GetModulePcdList
)
1945 LibraryPcdList
= property(_GetLibraryPcdList
)
1946 GuidList
= property(_GetGuidList
)
1947 ProtocolList
= property(_GetProtocolList
)
1948 PpiList
= property(_GetPpiList
)
1949 DepexList
= property(_GetDepexTokenList
)
1950 BuildOption
= property(_GetModuleBuildOption
)
1951 BuildCommand
= property(_GetBuildCommand
)
1953 # This acts like the main() function for the script, unless it is 'import'ed into another script.
1954 if __name__
== '__main__':