2 # Generate AutoGen.h, AutoGen.c and *.depex files
4 # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 import os
.path
as path
24 from StringIO
import StringIO
26 from StrGather
import *
27 from BuildEngine
import BuildRule
29 from Common
.BuildToolError
import *
30 from Common
.DataType
import *
31 from Common
.Misc
import *
32 from Common
.String
import *
33 import Common
.GlobalData
as GlobalData
34 from GenFds
.FdfParser
import *
35 from CommonDataClass
.CommonClass
import SkuInfoClass
36 from Workspace
.BuildClassObject
import *
37 import Common
.VpdInfoFile
as VpdInfoFile
39 ## Regular expression for splitting Dependency Expression stirng into tokens
40 gDepexTokenPattern
= re
.compile("(\(|\)|\w+| \S+\.inf)")
42 ## Mapping Makefile type
43 gMakeTypeMap
= {"MSFT":"nmake", "GCC":"gmake"}
46 ## Build rule configuration file
47 gBuildRuleFile
= 'Conf/build_rule.txt'
49 ## default file name for AutoGen
50 gAutoGenCodeFileName
= "AutoGen.c"
51 gAutoGenHeaderFileName
= "AutoGen.h"
52 gAutoGenStringFileName
= "%(module_name)sStrDefs.h"
53 gAutoGenStringFormFileName
= "%(module_name)sStrDefs.hpk"
54 gAutoGenDepexFileName
= "%(module_name)s.depex"
56 ## Base class for AutoGen
58 # This class just implements the cache mechanism of AutoGen objects.
60 class AutoGen(object):
61 # database to maintain the objects of xxxAutoGen
62 _CACHE_
= {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}
66 # @param Class class object of real AutoGen class
67 # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
68 # @param Workspace Workspace directory or WorkspaceAutoGen object
69 # @param MetaFile The path of meta file
70 # @param Target Build target
71 # @param Toolchain Tool chain name
72 # @param Arch Target arch
73 # @param *args The specific class related parameters
74 # @param **kwargs The specific class related dict parameters
76 def __new__(Class
, Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
77 # check if the object has been created
78 Key
= (Target
, Toolchain
)
79 if Key
not in Class
._CACHE
_ or Arch
not in Class
._CACHE
_[Key
] \
80 or MetaFile
not in Class
._CACHE
_[Key
][Arch
]:
81 AutoGenObject
= super(AutoGen
, Class
).__new
__(Class
)
82 # call real constructor
83 if not AutoGenObject
._Init
(Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
85 if Key
not in Class
._CACHE
_:
86 Class
._CACHE
_[Key
] = {}
87 if Arch
not in Class
._CACHE
_[Key
]:
88 Class
._CACHE
_[Key
][Arch
] = {}
89 Class
._CACHE
_[Key
][Arch
][MetaFile
] = AutoGenObject
91 AutoGenObject
= Class
._CACHE
_[Key
][Arch
][MetaFile
]
97 # The file path of platform file will be used to represent hash value of this object
99 # @retval int Hash value of the file path of platform file
102 return hash(self
.MetaFile
)
106 # The file path of platform file will be used to represent this object
108 # @retval string String of platform file path
111 return str(self
.MetaFile
)
114 def __eq__(self
, Other
):
115 return Other
and self
.MetaFile
== Other
117 ## Workspace AutoGen class
119 # This class is used mainly to control the whole platform build for different
120 # architecture. This class will generate top level makefile.
122 class WorkspaceAutoGen(AutoGen
):
123 ## Real constructor of WorkspaceAutoGen
125 # This method behaves the same as __init__ except that it needs explict invoke
126 # (in super class's __new__ method)
128 # @param WorkspaceDir Root directory of workspace
129 # @param ActivePlatform Meta-file of active platform
130 # @param Target Build target
131 # @param Toolchain Tool chain name
132 # @param ArchList List of architecture of current build
133 # @param MetaFileDb Database containing meta-files
134 # @param BuildConfig Configuration of build
135 # @param ToolDefinition Tool chain definitions
136 # @param FlashDefinitionFile File of flash definition
137 # @param Fds FD list to be generated
138 # @param Fvs FV list to be generated
139 # @param SkuId SKU id from command line
141 def _Init(self
, WorkspaceDir
, ActivePlatform
, Target
, Toolchain
, ArchList
, MetaFileDb
,
142 BuildConfig
, ToolDefinition
, FlashDefinitionFile
='', Fds
=[], Fvs
=[], SkuId
='', UniFlag
=None):
143 self
.MetaFile
= ActivePlatform
.MetaFile
144 self
.WorkspaceDir
= WorkspaceDir
145 self
.Platform
= ActivePlatform
146 self
.BuildTarget
= Target
147 self
.ToolChain
= Toolchain
148 self
.ArchList
= ArchList
150 self
.UniFlag
= UniFlag
152 self
.BuildDatabase
= MetaFileDb
153 self
.TargetTxt
= BuildConfig
154 self
.ToolDef
= ToolDefinition
155 self
.FdfFile
= FlashDefinitionFile
156 self
.FdTargetList
= Fds
157 self
.FvTargetList
= Fvs
158 self
.AutoGenObjectList
= []
160 # there's many relative directory operations, so ...
161 os
.chdir(self
.WorkspaceDir
)
163 # parse FDF file to get PCDs in it, if any
164 if self
.FdfFile
!= None and self
.FdfFile
!= '':
166 # Make global macros available when parsing FDF file
168 InputMacroDict
.update(self
.BuildDatabase
.WorkspaceDb
._GlobalMacros
)
169 Fdf
= FdfParser(self
.FdfFile
.Path
)
171 PcdSet
= Fdf
.Profile
.PcdDict
172 ModuleList
= Fdf
.Profile
.InfList
173 self
.FdfProfile
= Fdf
.Profile
177 self
.FdfProfile
= None
179 # apply SKU and inject PCDs from Flash Definition file
180 for Arch
in self
.ArchList
:
181 Platform
= self
.BuildDatabase
[self
.MetaFile
, Arch
]
182 Platform
.SkuName
= self
.SkuId
183 for Name
, Guid
in PcdSet
:
184 Platform
.AddPcd(Name
, Guid
, PcdSet
[Name
, Guid
])
186 Pa
= PlatformAutoGen(self
, self
.MetaFile
, Target
, Toolchain
, Arch
)
188 # Explicitly collect platform's dynamic PCDs
190 Pa
.CollectPlatformDynamicPcds()
191 self
.AutoGenObjectList
.append(Pa
)
194 # Check PCDs token value conflict in each DEC file.
196 self
._CheckAllPcdsTokenValueConflict
()
198 self
._BuildDir
= None
200 self
._MakeFileDir
= None
201 self
._BuildCommand
= None
206 return "%s [%s]" % (self
.MetaFile
, ", ".join(self
.ArchList
))
208 ## Return the directory to store FV files
210 if self
._FvDir
== None:
211 self
._FvDir
= path
.join(self
.BuildDir
, 'FV')
214 ## Return the directory to store all intermediate and final files built
215 def _GetBuildDir(self
):
216 return self
.AutoGenObjectList
[0].BuildDir
218 ## Return the build output directory platform specifies
219 def _GetOutputDir(self
):
220 return self
.Platform
.OutputDirectory
222 ## Return platform name
224 return self
.Platform
.PlatformName
226 ## Return meta-file GUID
228 return self
.Platform
.Guid
230 ## Return platform version
231 def _GetVersion(self
):
232 return self
.Platform
.Version
234 ## Return paths of tools
235 def _GetToolDefinition(self
):
236 return self
.AutoGenObjectList
[0].ToolDefinition
238 ## Return directory of platform makefile
240 # @retval string Makefile directory
242 def _GetMakeFileDir(self
):
243 if self
._MakeFileDir
== None:
244 self
._MakeFileDir
= self
.BuildDir
245 return self
._MakeFileDir
247 ## Return build command string
249 # @retval string Build command string
251 def _GetBuildCommand(self
):
252 if self
._BuildCommand
== None:
253 # BuildCommand should be all the same. So just get one from platform AutoGen
254 self
._BuildCommand
= self
.AutoGenObjectList
[0].BuildCommand
255 return self
._BuildCommand
257 ## Check the PCDs token value conflict in each DEC file.
259 # Will cause build break and raise error message while two PCDs conflict.
263 def _CheckAllPcdsTokenValueConflict(self
):
264 if len(self
.BuildDatabase
.WorkspaceDb
.PackageList
) >= 1:
265 for Package
in self
.BuildDatabase
.WorkspaceDb
.PackageList
:
266 PcdList
= Package
.Pcds
.values()
267 PcdList
.sort(lambda x
, y
: cmp(x
.TokenValue
, y
.TokenValue
))
269 while (Count
< len(PcdList
) - 1) :
270 Item
= PcdList
[Count
]
271 ItemNext
= PcdList
[Count
+ 1]
273 # Make sure in the same token space the TokenValue should be unique
275 if (Item
.TokenValue
== ItemNext
.TokenValue
):
276 SameTokenValuePcdList
= []
277 SameTokenValuePcdList
.append(Item
)
278 SameTokenValuePcdList
.append(ItemNext
)
279 RemainPcdListLength
= len(PcdList
) - Count
- 2
280 for ValueSameCount
in range(RemainPcdListLength
):
281 if PcdList
[len(PcdList
) - RemainPcdListLength
+ ValueSameCount
].TokenValue
== Item
.TokenValue
:
282 SameTokenValuePcdList
.append(PcdList
[len(PcdList
) - RemainPcdListLength
+ ValueSameCount
])
286 # Sort same token value PCD list with TokenGuid and TokenCName
288 SameTokenValuePcdList
.sort(lambda x
, y
: cmp("%s.%s"%(x
.TokenSpaceGuidCName
, x
.TokenCName
), "%s.%s"%(y
.TokenSpaceGuidCName
, y
.TokenCName
)))
289 SameTokenValuePcdListCount
= 0
290 while (SameTokenValuePcdListCount
< len(SameTokenValuePcdList
) - 1):
291 TemListItem
= SameTokenValuePcdList
[SameTokenValuePcdListCount
]
292 TemListItemNext
= SameTokenValuePcdList
[SameTokenValuePcdListCount
+ 1]
294 if (TemListItem
.TokenSpaceGuidCName
== TemListItemNext
.TokenSpaceGuidCName
) and (TemListItem
.TokenCName
!= TemListItemNext
.TokenCName
):
298 "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\
299 % (TemListItem
.TokenValue
, TemListItem
.TokenSpaceGuidCName
, TemListItem
.TokenCName
, TemListItemNext
.TokenSpaceGuidCName
, TemListItemNext
.TokenCName
, Package
),
302 SameTokenValuePcdListCount
+= 1
303 Count
+= SameTokenValuePcdListCount
306 PcdList
= Package
.Pcds
.values()
307 PcdList
.sort(lambda x
, y
: cmp("%s.%s"%(x
.TokenSpaceGuidCName
, x
.TokenCName
), "%s.%s"%(y
.TokenSpaceGuidCName
, y
.TokenCName
)))
309 while (Count
< len(PcdList
) - 1) :
310 Item
= PcdList
[Count
]
311 ItemNext
= PcdList
[Count
+ 1]
313 # Check PCDs with same TokenSpaceGuidCName.TokenCName have same token value as well.
315 if (Item
.TokenSpaceGuidCName
== ItemNext
.TokenSpaceGuidCName
) and (Item
.TokenCName
== ItemNext
.TokenCName
) and (Item
.TokenValue
!= ItemNext
.TokenValue
):
319 "The TokenValue [%s] of PCD [%s.%s] in %s defined in two places should be same as well."\
320 % (Item
.TokenValue
, Item
.TokenSpaceGuidCName
, Item
.TokenCName
, Package
),
326 ## Create makefile for the platform and modules in it
328 # @param CreateDepsMakeFile Flag indicating if the makefile for
329 # modules will be created as well
331 def CreateMakeFile(self
, CreateDepsMakeFile
=False):
332 # create makefile for platform
333 Makefile
= GenMake
.TopLevelMakefile(self
)
334 if Makefile
.Generate():
335 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for platform [%s] %s\n" %
336 (self
.MetaFile
, self
.ArchList
))
338 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for platform [%s] %s\n" %
339 (self
.MetaFile
, self
.ArchList
))
341 if CreateDepsMakeFile
:
342 for Pa
in self
.AutoGenObjectList
:
343 Pa
.CreateMakeFile(CreateDepsMakeFile
)
345 ## Create autogen code for platform and modules
347 # Since there's no autogen code for platform, this method will do nothing
348 # if CreateModuleCodeFile is set to False.
350 # @param CreateDepsCodeFile Flag indicating if creating module's
351 # autogen code file or not
353 def CreateCodeFile(self
, CreateDepsCodeFile
=False):
354 if not CreateDepsCodeFile
:
356 for Pa
in self
.AutoGenObjectList
:
357 Pa
.CreateCodeFile(CreateDepsCodeFile
)
359 Name
= property(_GetName
)
360 Guid
= property(_GetGuid
)
361 Version
= property(_GetVersion
)
362 OutputDir
= property(_GetOutputDir
)
364 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
366 BuildDir
= property(_GetBuildDir
)
367 FvDir
= property(_GetFvDir
)
368 MakeFileDir
= property(_GetMakeFileDir
)
369 BuildCommand
= property(_GetBuildCommand
)
371 ## AutoGen class for platform
373 # PlatformAutoGen class will process the original information in platform
374 # file in order to generate makefile for platform.
376 class PlatformAutoGen(AutoGen
):
378 # Used to store all PCDs for both PEI and DXE phase, in order to generate
379 # correct PCD database
382 _NonDynaPcdList_
= []
385 # The priority list while override build option
387 PrioList
= {"0x11111" : 16, # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest)
388 "0x01111" : 15, # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
389 "0x10111" : 14, # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE
390 "0x00111" : 13, # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE
391 "0x11011" : 12, # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
392 "0x01011" : 11, # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
393 "0x10011" : 10, # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE
394 "0x00011" : 9, # ******_*********_****_COMMANDTYPE_ATTRIBUTE
395 "0x11101" : 8, # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE
396 "0x01101" : 7, # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE
397 "0x10101" : 6, # TARGET_*********_ARCH_***********_ATTRIBUTE
398 "0x00101" : 5, # ******_*********_ARCH_***********_ATTRIBUTE
399 "0x11001" : 4, # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE
400 "0x01001" : 3, # ******_TOOLCHAIN_****_***********_ATTRIBUTE
401 "0x10001" : 2, # TARGET_*********_****_***********_ATTRIBUTE
402 "0x00001" : 1} # ******_*********_****_***********_ATTRIBUTE (Lowest)
404 ## The real constructor of PlatformAutoGen
406 # This method is not supposed to be called by users of PlatformAutoGen. It's
407 # only used by factory method __new__() to do real initialization work for an
408 # object of PlatformAutoGen
410 # @param Workspace WorkspaceAutoGen object
411 # @param PlatformFile Platform file (DSC file)
412 # @param Target Build target (DEBUG, RELEASE)
413 # @param Toolchain Name of tool chain
414 # @param Arch arch of the platform supports
416 def _Init(self
, Workspace
, PlatformFile
, Target
, Toolchain
, Arch
):
417 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen platform [%s] [%s]" % (PlatformFile
, Arch
))
418 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (PlatformFile
, Arch
, Toolchain
, Target
)
420 self
.MetaFile
= PlatformFile
421 self
.Workspace
= Workspace
422 self
.WorkspaceDir
= Workspace
.WorkspaceDir
423 self
.ToolChain
= Toolchain
424 self
.BuildTarget
= Target
426 self
.SourceDir
= PlatformFile
.SubDir
427 self
.SourceOverrideDir
= None
428 self
.FdTargetList
= self
.Workspace
.FdTargetList
429 self
.FvTargetList
= self
.Workspace
.FvTargetList
432 # flag indicating if the makefile/C-code file has been created or not
433 self
.IsMakeFileCreated
= False
434 self
.IsCodeFileCreated
= False
436 self
._Platform
= None
441 self
._BuildRule
= None
442 self
._SourceDir
= None
443 self
._BuildDir
= None
444 self
._OutputDir
= None
446 self
._MakeFileDir
= None
449 self
._PcdTokenNumber
= None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
450 self
._DynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
451 self
._NonDynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
453 self
._ToolDefinitions
= None
454 self
._ToolDefFile
= None # toolcode : tool path
455 self
._ToolChainFamily
= None
456 self
._BuildRuleFamily
= None
457 self
._BuildOption
= None # toolcode : option
458 self
._EdkBuildOption
= None # edktoolcode : option
459 self
._EdkIIBuildOption
= None # edkiitoolcode : option
460 self
._PackageList
= None
461 self
._ModuleAutoGenList
= None
462 self
._LibraryAutoGenList
= None
463 self
._BuildCommand
= None
465 # get the original module/package/platform objects
466 self
.BuildDatabase
= Workspace
.BuildDatabase
470 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
472 ## Create autogen code for platform and modules
474 # Since there's no autogen code for platform, this method will do nothing
475 # if CreateModuleCodeFile is set to False.
477 # @param CreateModuleCodeFile Flag indicating if creating module's
478 # autogen code file or not
480 def CreateCodeFile(self
, CreateModuleCodeFile
=False):
481 # only module has code to be greated, so do nothing if CreateModuleCodeFile is False
482 if self
.IsCodeFileCreated
or not CreateModuleCodeFile
:
485 for Ma
in self
.ModuleAutoGenList
:
486 Ma
.CreateCodeFile(True)
488 # don't do this twice
489 self
.IsCodeFileCreated
= True
491 ## Create makefile for the platform and mdoules in it
493 # @param CreateModuleMakeFile Flag indicating if the makefile for
494 # modules will be created as well
496 def CreateMakeFile(self
, CreateModuleMakeFile
=False):
497 if CreateModuleMakeFile
:
498 for ModuleFile
in self
.Platform
.Modules
:
499 Ma
= ModuleAutoGen(self
.Workspace
, ModuleFile
, self
.BuildTarget
,
500 self
.ToolChain
, self
.Arch
, self
.MetaFile
)
501 Ma
.CreateMakeFile(True)
503 # no need to create makefile for the platform more than once
504 if self
.IsMakeFileCreated
:
507 # create makefile for platform
508 Makefile
= GenMake
.PlatformMakefile(self
)
509 if Makefile
.Generate():
510 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for platform [%s] [%s]\n" %
511 (self
.MetaFile
, self
.Arch
))
513 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for platform [%s] [%s]\n" %
514 (self
.MetaFile
, self
.Arch
))
515 self
.IsMakeFileCreated
= True
517 ## Collect dynamic PCDs
519 # Gather dynamic PCDs list from each module and their settings from platform
520 # This interface should be invoked explicitly when platform action is created.
522 def CollectPlatformDynamicPcds(self
):
523 # for gathering error information
524 NoDatumTypePcdList
= set()
527 for F
in self
.Platform
.Modules
.keys():
528 M
= ModuleAutoGen(self
.Workspace
, F
, self
.BuildTarget
, self
.ToolChain
, self
.Arch
, self
.MetaFile
)
529 #GuidValue.update(M.Guids)
531 self
.Platform
.Modules
[F
].M
= M
533 for PcdFromModule
in M
.ModulePcdList
+M
.LibraryPcdList
:
534 # make sure that the "VOID*" kind of datum has MaxDatumSize set
535 if PcdFromModule
.DatumType
== "VOID*" and PcdFromModule
.MaxDatumSize
== None:
536 NoDatumTypePcdList
.add("%s.%s [%s]" % (PcdFromModule
.TokenSpaceGuidCName
, PcdFromModule
.TokenCName
, F
))
538 if PcdFromModule
.Type
in GenC
.gDynamicPcd
or PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
540 # If a dynamic PCD used by a PEM module/PEI module & DXE module,
541 # it should be stored in Pcd PEI database, If a dynamic only
542 # used by DXE module, it should be stored in DXE PCD database.
543 # The default Phase is DXE
545 if M
.ModuleType
in ["PEIM", "PEI_CORE"]:
546 PcdFromModule
.Phase
= "PEI"
547 if PcdFromModule
not in self
._DynaPcdList
_:
548 self
._DynaPcdList
_.append(PcdFromModule
)
549 elif PcdFromModule
.Phase
== 'PEI':
550 # overwrite any the same PCD existing, if Phase is PEI
551 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
552 self
._DynaPcdList
_[Index
] = PcdFromModule
553 elif PcdFromModule
not in self
._NonDynaPcdList
_:
554 self
._NonDynaPcdList
_.append(PcdFromModule
)
556 # print out error information and break the build, if error found
557 if len(NoDatumTypePcdList
) > 0:
558 NoDatumTypePcdListString
= "\n\t\t".join(NoDatumTypePcdList
)
559 EdkLogger
.error("build", AUTOGEN_ERROR
, "PCD setting error",
561 ExtraData
="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
562 % NoDatumTypePcdListString
)
563 self
._NonDynamicPcdList
= self
._NonDynaPcdList
_
564 self
._DynamicPcdList
= self
._DynaPcdList
_
565 self
.AllPcdList
= self
._NonDynamicPcdList
+ self
._DynamicPcdList
568 # Sort dynamic PCD list to:
569 # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should
570 # try to be put header of dynamicd List
571 # 2) If PCD is HII type, the PCD item should be put after unicode type PCD
573 # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.
579 VpdFile
= VpdInfoFile
.VpdInfoFile()
580 NeedProcessVpdMapFile
= False
582 if (self
.Workspace
.ArchList
[-1] == self
.Arch
):
583 for Pcd
in self
._DynamicPcdList
:
584 # just pick the a value to determine whether is unicode string type
585 Sku
= Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]]
586 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
588 PcdValue
= Sku
.DefaultValue
589 if Pcd
.DatumType
== 'VOID*' and PcdValue
.startswith("L"):
590 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
591 UnicodePcdArray
.append(Pcd
)
592 elif len(Sku
.VariableName
) > 0:
593 # if found HII type PCD then insert to right of UnicodeIndex
594 HiiPcdArray
.append(Pcd
)
596 OtherPcdArray
.append(Pcd
)
597 if Pcd
.Type
in [TAB_PCDS_DYNAMIC_VPD
, TAB_PCDS_DYNAMIC_EX_VPD
]:
598 VpdPcdDict
[(Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
)] = Pcd
600 PlatformPcds
= self
.Platform
.Pcds
.keys()
603 # Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up.
605 for PcdKey
in PlatformPcds
:
606 Pcd
= self
.Platform
.Pcds
[PcdKey
]
607 if Pcd
.Type
in [TAB_PCDS_DYNAMIC_VPD
, TAB_PCDS_DYNAMIC_EX_VPD
]:
608 Pcd
= VpdPcdDict
[PcdKey
]
609 Sku
= Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]]
610 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
612 # Fix the optional data of VPD PCD.
614 if (Pcd
.DatumType
.strip() != "VOID*"):
615 if Sku
.DefaultValue
== '':
616 Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]].DefaultValue
= Pcd
.MaxDatumSize
617 Pcd
.MaxDatumSize
= None
619 EdkLogger
.error("build", AUTOGEN_ERROR
, "PCD setting error",
621 ExtraData
="\n\tPCD: %s.%s format incorrect in DSC: %s\n\t\t\n"
622 % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, self
.Platform
.MetaFile
.Path
))
624 VpdFile
.Add(Pcd
, Sku
.VpdOffset
)
625 # if the offset of a VPD is *, then it need to be fixed up by third party tool.
626 if not NeedProcessVpdMapFile
and Sku
.VpdOffset
== "*":
627 NeedProcessVpdMapFile
= True
628 if self
.Platform
.VpdToolGuid
== None or self
.Platform
.VpdToolGuid
== '':
629 EdkLogger
.error("Build", FILE_NOT_FOUND
, \
630 "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")
634 # Fix the PCDs define in VPD PCD section that never referenced by module.
635 # An example is PCD for signature usage.
637 for DscPcd
in PlatformPcds
:
638 DscPcdEntry
= self
.Platform
.Pcds
[DscPcd
]
639 if DscPcdEntry
.Type
in [TAB_PCDS_DYNAMIC_VPD
, TAB_PCDS_DYNAMIC_EX_VPD
]:
640 if not (self
.Platform
.VpdToolGuid
== None or self
.Platform
.VpdToolGuid
== ''):
642 for VpdPcd
in VpdFile
._VpdArray
.keys():
643 # This PCD has been referenced by module
644 if (VpdPcd
.TokenSpaceGuidCName
== DscPcdEntry
.TokenSpaceGuidCName
) and \
645 (VpdPcd
.TokenCName
== DscPcdEntry
.TokenCName
):
648 # Not found, it should be signature
650 # just pick the a value to determine whether is unicode string type
651 Sku
= DscPcdEntry
.SkuInfoList
[DscPcdEntry
.SkuInfoList
.keys()[0]]
652 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
654 # Need to iterate DEC pcd information to get the value & datumtype
655 for eachDec
in self
.PackageList
:
656 for DecPcd
in eachDec
.Pcds
:
657 DecPcdEntry
= eachDec
.Pcds
[DecPcd
]
658 if (DecPcdEntry
.TokenSpaceGuidCName
== DscPcdEntry
.TokenSpaceGuidCName
) and \
659 (DecPcdEntry
.TokenCName
== DscPcdEntry
.TokenCName
):
660 # Print warning message to let the developer make a determine.
661 EdkLogger
.warn("build", "Unreferenced vpd pcd used!",
662 File
=self
.MetaFile
, \
663 ExtraData
= "PCD: %s.%s used in the DSC file %s is unreferenced." \
664 %(DscPcdEntry
.TokenSpaceGuidCName
, DscPcdEntry
.TokenCName
, self
.Platform
.MetaFile
.Path
))
666 DscPcdEntry
.DatumType
= DecPcdEntry
.DatumType
667 DscPcdEntry
.DefaultValue
= DecPcdEntry
.DefaultValue
668 # Only fix the value while no value provided in DSC file.
669 if (Sku
.DefaultValue
== "" or Sku
.DefaultValue
==None):
670 DscPcdEntry
.SkuInfoList
[DscPcdEntry
.SkuInfoList
.keys()[0]].DefaultValue
= DecPcdEntry
.DefaultValue
673 VpdFile
.Add(DscPcdEntry
, Sku
.VpdOffset
)
674 # if the offset of a VPD is *, then it need to be fixed up by third party tool.
675 if not NeedProcessVpdMapFile
and Sku
.VpdOffset
== "*":
676 NeedProcessVpdMapFile
= True
679 if (self
.Platform
.FlashDefinition
== None or self
.Platform
.FlashDefinition
== '') and \
680 VpdFile
.GetCount() != 0:
681 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
682 "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self
.Platform
.MetaFile
))
684 if VpdFile
.GetCount() != 0:
685 WorkspaceDb
= self
.BuildDatabase
.WorkspaceDb
686 DscTimeStamp
= WorkspaceDb
.GetTimeStamp(WorkspaceDb
.GetFileId(str(self
.Platform
.MetaFile
)))
687 FvPath
= os
.path
.join(self
.BuildDir
, "FV")
688 if not os
.path
.exists(FvPath
):
692 EdkLogger
.error("build", FILE_WRITE_FAILURE
, "Fail to create FV folder under %s" % self
.BuildDir
)
695 VpdFilePath
= os
.path
.join(FvPath
, "%s.txt" % self
.Platform
.VpdToolGuid
)
698 if not os
.path
.exists(VpdFilePath
) or os
.path
.getmtime(VpdFilePath
) < DscTimeStamp
:
699 VpdFile
.Write(VpdFilePath
)
701 # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file.
703 for ToolDef
in self
.ToolDefinition
.values():
704 if ToolDef
.has_key("GUID") and ToolDef
["GUID"] == self
.Platform
.VpdToolGuid
:
705 if not ToolDef
.has_key("PATH"):
706 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self
.Platform
.VpdToolGuid
)
707 BPDGToolName
= ToolDef
["PATH"]
709 # Call third party GUID BPDG tool.
710 if BPDGToolName
!= None:
711 VpdInfoFile
.CallExtenalBPDGTool(BPDGToolName
, VpdFilePath
)
713 EdkLogger
.error("Build", FILE_NOT_FOUND
, "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")
715 # Process VPD map file generated by third party BPDG tool
716 if NeedProcessVpdMapFile
:
717 VpdMapFilePath
= os
.path
.join(self
.BuildDir
, "FV", "%s.map" % self
.Platform
.VpdToolGuid
)
718 if os
.path
.exists(VpdMapFilePath
):
719 VpdFile
.Read(VpdMapFilePath
)
722 for Pcd
in self
._DynamicPcdList
:
723 # just pick the a value to determine whether is unicode string type
724 Sku
= Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]]
725 if Sku
.VpdOffset
== "*":
726 Sku
.VpdOffset
= VpdFile
.GetOffset(Pcd
)[0]
728 EdkLogger
.error("build", FILE_READ_FAILURE
, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath
)
730 # Delete the DynamicPcdList At the last time enter into this function
731 del self
._DynamicPcdList
[:]
732 self
._DynamicPcdList
.extend(UnicodePcdArray
)
733 self
._DynamicPcdList
.extend(HiiPcdArray
)
734 self
._DynamicPcdList
.extend(OtherPcdArray
)
737 ## Return the platform build data object
738 def _GetPlatform(self
):
739 if self
._Platform
== None:
740 self
._Platform
= self
.BuildDatabase
[self
.MetaFile
, self
.Arch
]
741 return self
._Platform
743 ## Return platform name
745 return self
.Platform
.PlatformName
747 ## Return the meta file GUID
749 return self
.Platform
.Guid
751 ## Return the platform version
752 def _GetVersion(self
):
753 return self
.Platform
.Version
755 ## Return the FDF file name
756 def _GetFdfFile(self
):
757 if self
._FdfFile
== None:
758 if self
.Workspace
.FdfFile
!= "":
759 self
._FdfFile
= path
.join(self
.WorkspaceDir
, self
.Workspace
.FdfFile
)
764 ## Return the build output directory platform specifies
765 def _GetOutputDir(self
):
766 return self
.Platform
.OutputDirectory
768 ## Return the directory to store all intermediate and final files built
769 def _GetBuildDir(self
):
770 if self
._BuildDir
== None:
771 if os
.path
.isabs(self
.OutputDir
):
772 self
._BuildDir
= path
.join(
773 path
.abspath(self
.OutputDir
),
774 self
.BuildTarget
+ "_" + self
.ToolChain
,
777 self
._BuildDir
= path
.join(
780 self
.BuildTarget
+ "_" + self
.ToolChain
,
782 return self
._BuildDir
784 ## Return directory of platform makefile
786 # @retval string Makefile directory
788 def _GetMakeFileDir(self
):
789 if self
._MakeFileDir
== None:
790 self
._MakeFileDir
= path
.join(self
.BuildDir
, self
.Arch
)
791 return self
._MakeFileDir
793 ## Return build command string
795 # @retval string Build command string
797 def _GetBuildCommand(self
):
798 if self
._BuildCommand
== None:
799 self
._BuildCommand
= []
800 if "MAKE" in self
.ToolDefinition
and "PATH" in self
.ToolDefinition
["MAKE"]:
801 self
._BuildCommand
+= SplitOption(self
.ToolDefinition
["MAKE"]["PATH"])
802 if "FLAGS" in self
.ToolDefinition
["MAKE"]:
803 NewOption
= self
.ToolDefinition
["MAKE"]["FLAGS"].strip()
805 self
._BuildCommand
+= SplitOption(NewOption
)
806 return self
._BuildCommand
808 ## Get tool chain definition
810 # Get each tool defition for given tool chain from tools_def.txt and platform
812 def _GetToolDefinition(self
):
813 if self
._ToolDefinitions
== None:
814 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDictionary
815 if TAB_TOD_DEFINES_COMMAND_TYPE
not in self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
:
816 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No tools found in configuration",
817 ExtraData
="[%s]" % self
.MetaFile
)
818 self
._ToolDefinitions
= {}
820 for Def
in ToolDefinition
:
821 Target
, Tag
, Arch
, Tool
, Attr
= Def
.split("_")
822 if Target
!= self
.BuildTarget
or Tag
!= self
.ToolChain
or Arch
!= self
.Arch
:
825 Value
= ToolDefinition
[Def
]
826 # don't record the DLL
828 DllPathList
.add(Value
)
831 if Tool
not in self
._ToolDefinitions
:
832 self
._ToolDefinitions
[Tool
] = {}
833 self
._ToolDefinitions
[Tool
][Attr
] = Value
837 if GlobalData
.gOptions
.SilentMode
and "MAKE" in self
._ToolDefinitions
:
838 if "FLAGS" not in self
._ToolDefinitions
["MAKE"]:
839 self
._ToolDefinitions
["MAKE"]["FLAGS"] = ""
840 self
._ToolDefinitions
["MAKE"]["FLAGS"] += " -s"
842 for Tool
in self
._ToolDefinitions
:
843 for Attr
in self
._ToolDefinitions
[Tool
]:
844 Value
= self
._ToolDefinitions
[Tool
][Attr
]
845 if Tool
in self
.BuildOption
and Attr
in self
.BuildOption
[Tool
]:
846 # check if override is indicated
847 if self
.BuildOption
[Tool
][Attr
].startswith('='):
848 Value
= self
.BuildOption
[Tool
][Attr
][1:]
850 Value
+= " " + self
.BuildOption
[Tool
][Attr
]
853 # Don't put MAKE definition in the file
857 ToolsDef
+= "%s = %s\n" % (Tool
, Value
)
859 # Don't put MAKE definition in the file
864 ToolsDef
+= "%s_%s = %s\n" % (Tool
, Attr
, Value
)
867 SaveFileOnChange(self
.ToolDefinitionFile
, ToolsDef
)
868 for DllPath
in DllPathList
:
869 os
.environ
["PATH"] = DllPath
+ os
.pathsep
+ os
.environ
["PATH"]
870 os
.environ
["MAKE_FLAGS"] = MakeFlags
872 return self
._ToolDefinitions
874 ## Return the paths of tools
875 def _GetToolDefFile(self
):
876 if self
._ToolDefFile
== None:
877 self
._ToolDefFile
= os
.path
.join(self
.MakeFileDir
, "TOOLS_DEF." + self
.Arch
)
878 return self
._ToolDefFile
880 ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.
881 def _GetToolChainFamily(self
):
882 if self
._ToolChainFamily
== None:
883 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
884 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
885 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
886 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]:
887 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
889 self
._ToolChainFamily
= "MSFT"
891 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]
892 return self
._ToolChainFamily
894 def _GetBuildRuleFamily(self
):
895 if self
._BuildRuleFamily
== None:
896 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
897 if TAB_TOD_DEFINES_BUILDRULEFAMILY
not in ToolDefinition \
898 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
] \
899 or not ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]:
900 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
902 self
._BuildRuleFamily
= "MSFT"
904 self
._BuildRuleFamily
= ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]
905 return self
._BuildRuleFamily
907 ## Return the build options specific for all modules in this platform
908 def _GetBuildOptions(self
):
909 if self
._BuildOption
== None:
910 self
._BuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
)
911 return self
._BuildOption
913 ## Return the build options specific for EDK modules in this platform
914 def _GetEdkBuildOptions(self
):
915 if self
._EdkBuildOption
== None:
916 self
._EdkBuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
, EDK_NAME
)
917 return self
._EdkBuildOption
919 ## Return the build options specific for EDKII modules in this platform
920 def _GetEdkIIBuildOptions(self
):
921 if self
._EdkIIBuildOption
== None:
922 self
._EdkIIBuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
, EDKII_NAME
)
923 return self
._EdkIIBuildOption
925 ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt
927 # @retval BuildRule object
929 def _GetBuildRule(self
):
930 if self
._BuildRule
== None:
932 if TAB_TAT_DEFINES_BUILD_RULE_CONF
in self
.Workspace
.TargetTxt
.TargetTxtDictionary
:
933 BuildRuleFile
= self
.Workspace
.TargetTxt
.TargetTxtDictionary
[TAB_TAT_DEFINES_BUILD_RULE_CONF
]
934 if BuildRuleFile
in [None, '']:
935 BuildRuleFile
= gBuildRuleFile
936 self
._BuildRule
= BuildRule(BuildRuleFile
)
937 return self
._BuildRule
939 ## Summarize the packages used by modules in this platform
940 def _GetPackageList(self
):
941 if self
._PackageList
== None:
942 self
._PackageList
= set()
943 for La
in self
.LibraryAutoGenList
:
944 self
._PackageList
.update(La
.DependentPackageList
)
945 for Ma
in self
.ModuleAutoGenList
:
946 self
._PackageList
.update(Ma
.DependentPackageList
)
947 self
._PackageList
= list(self
._PackageList
)
948 return self
._PackageList
950 ## Get list of non-dynamic PCDs
951 def _GetNonDynamicPcdList(self
):
952 if self
._NonDynamicPcdList
== None:
953 self
.CollectPlatformDynamicPcds()
954 return self
._NonDynamicPcdList
956 ## Get list of dynamic PCDs
957 def _GetDynamicPcdList(self
):
958 if self
._DynamicPcdList
== None:
959 self
.CollectPlatformDynamicPcds()
960 return self
._DynamicPcdList
962 ## Generate Token Number for all PCD
963 def _GetPcdTokenNumbers(self
):
964 if self
._PcdTokenNumber
== None:
965 self
._PcdTokenNumber
= sdict()
967 for Pcd
in self
.DynamicPcdList
:
968 if Pcd
.Phase
== "PEI":
969 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
970 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
973 for Pcd
in self
.DynamicPcdList
:
974 if Pcd
.Phase
== "DXE":
975 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
976 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
979 for Pcd
in self
.NonDynamicPcdList
:
980 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
982 return self
._PcdTokenNumber
984 ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform
985 def _GetAutoGenObjectList(self
):
986 self
._ModuleAutoGenList
= []
987 self
._LibraryAutoGenList
= []
988 for ModuleFile
in self
.Platform
.Modules
:
997 if Ma
not in self
._ModuleAutoGenList
:
998 self
._ModuleAutoGenList
.append(Ma
)
999 for La
in Ma
.LibraryAutoGenList
:
1000 if La
not in self
._LibraryAutoGenList
:
1001 self
._LibraryAutoGenList
.append(La
)
1003 ## Summarize ModuleAutoGen objects of all modules to be built for this platform
1004 def _GetModuleAutoGenList(self
):
1005 if self
._ModuleAutoGenList
== None:
1006 self
._GetAutoGenObjectList
()
1007 return self
._ModuleAutoGenList
1009 ## Summarize ModuleAutoGen objects of all libraries to be built for this platform
1010 def _GetLibraryAutoGenList(self
):
1011 if self
._LibraryAutoGenList
== None:
1012 self
._GetAutoGenObjectList
()
1013 return self
._LibraryAutoGenList
1015 ## Test if a module is supported by the platform
1017 # An error will be raised directly if the module or its arch is not supported
1018 # by the platform or current configuration
1020 def ValidModule(self
, Module
):
1021 return Module
in self
.Platform
.Modules
or Module
in self
.Platform
.LibraryInstances
1023 ## Resolve the library classes in a module to library instances
1025 # This method will not only resolve library classes but also sort the library
1026 # instances according to the dependency-ship.
1028 # @param Module The module from which the library classes will be resolved
1030 # @retval library_list List of library instances sorted
1032 def ApplyLibraryInstance(self
, Module
):
1033 ModuleType
= Module
.ModuleType
1035 # for overridding library instances with module specific setting
1036 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1038 # add forced library instances (specified under LibraryClasses sections)
1039 for LibraryClass
in self
.Platform
.LibraryClasses
.GetKeys():
1040 if LibraryClass
.startswith("NULL"):
1041 Module
.LibraryClasses
[LibraryClass
] = self
.Platform
.LibraryClasses
[LibraryClass
]
1043 # add forced library instances (specified in module overrides)
1044 for LibraryClass
in PlatformModule
.LibraryClasses
:
1045 if LibraryClass
.startswith("NULL"):
1046 Module
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
1049 LibraryConsumerList
= [Module
]
1051 ConsumedByList
= sdict()
1052 LibraryInstance
= sdict()
1054 EdkLogger
.verbose("")
1055 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
1056 while len(LibraryConsumerList
) > 0:
1057 M
= LibraryConsumerList
.pop()
1058 for LibraryClassName
in M
.LibraryClasses
:
1059 if LibraryClassName
not in LibraryInstance
:
1060 # override library instance for this module
1061 if LibraryClassName
in PlatformModule
.LibraryClasses
:
1062 LibraryPath
= PlatformModule
.LibraryClasses
[LibraryClassName
]
1064 LibraryPath
= self
.Platform
.LibraryClasses
[LibraryClassName
, ModuleType
]
1065 if LibraryPath
== None or LibraryPath
== "":
1066 LibraryPath
= M
.LibraryClasses
[LibraryClassName
]
1067 if LibraryPath
== None or LibraryPath
== "":
1068 EdkLogger
.error("build", RESOURCE_NOT_AVAILABLE
,
1069 "Instance of library class [%s] is not found" % LibraryClassName
,
1071 ExtraData
="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M
), self
.Arch
, str(Module
)))
1073 LibraryModule
= self
.BuildDatabase
[LibraryPath
, self
.Arch
]
1074 # for those forced library instance (NULL library), add a fake library class
1075 if LibraryClassName
.startswith("NULL"):
1076 LibraryModule
.LibraryClass
.append(LibraryClassObject(LibraryClassName
, [ModuleType
]))
1077 elif LibraryModule
.LibraryClass
== None \
1078 or len(LibraryModule
.LibraryClass
) == 0 \
1079 or (ModuleType
!= 'USER_DEFINED'
1080 and ModuleType
not in LibraryModule
.LibraryClass
[0].SupModList
):
1081 # only USER_DEFINED can link against any library instance despite of its SupModList
1082 EdkLogger
.error("build", OPTION_MISSING
,
1083 "Module type [%s] is not supported by library instance [%s]" \
1084 % (ModuleType
, LibraryPath
), File
=self
.MetaFile
,
1085 ExtraData
="consumed by [%s]" % str(Module
))
1087 LibraryInstance
[LibraryClassName
] = LibraryModule
1088 LibraryConsumerList
.append(LibraryModule
)
1089 EdkLogger
.verbose("\t" + str(LibraryClassName
) + " : " + str(LibraryModule
))
1091 LibraryModule
= LibraryInstance
[LibraryClassName
]
1093 if LibraryModule
== None:
1096 if LibraryModule
.ConstructorList
!= [] and LibraryModule
not in Constructor
:
1097 Constructor
.append(LibraryModule
)
1099 if LibraryModule
not in ConsumedByList
:
1100 ConsumedByList
[LibraryModule
] = []
1101 # don't add current module itself to consumer list
1103 if M
in ConsumedByList
[LibraryModule
]:
1105 ConsumedByList
[LibraryModule
].append(M
)
1107 # Initialize the sorted output list to the empty set
1109 SortedLibraryList
= []
1111 # Q <- Set of all nodes with no incoming edges
1113 LibraryList
= [] #LibraryInstance.values()
1115 for LibraryClassName
in LibraryInstance
:
1116 M
= LibraryInstance
[LibraryClassName
]
1117 LibraryList
.append(M
)
1118 if ConsumedByList
[M
] == []:
1122 # start the DAG algorithm
1126 while Q
== [] and EdgeRemoved
:
1128 # for each node Item with a Constructor
1129 for Item
in LibraryList
:
1130 if Item
not in Constructor
:
1132 # for each Node without a constructor with an edge e from Item to Node
1133 for Node
in ConsumedByList
[Item
]:
1134 if Node
in Constructor
:
1136 # remove edge e from the graph if Node has no constructor
1137 ConsumedByList
[Item
].remove(Node
)
1139 if ConsumedByList
[Item
] == []:
1140 # insert Item into Q
1145 # DAG is done if there's no more incoming edge for all nodes
1149 # remove node from Q
1152 SortedLibraryList
.append(Node
)
1154 # for each node Item with an edge e from Node to Item do
1155 for Item
in LibraryList
:
1156 if Node
not in ConsumedByList
[Item
]:
1158 # remove edge e from the graph
1159 ConsumedByList
[Item
].remove(Node
)
1161 if ConsumedByList
[Item
] != []:
1163 # insert Item into Q, if Item has no other incoming edges
1167 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
1169 for Item
in LibraryList
:
1170 if ConsumedByList
[Item
] != [] and Item
in Constructor
and len(Constructor
) > 1:
1171 ErrorMessage
= "\tconsumed by " + "\n\tconsumed by ".join([str(L
) for L
in ConsumedByList
[Item
]])
1172 EdkLogger
.error("build", BUILD_ERROR
, 'Library [%s] with constructors has a cycle' % str(Item
),
1173 ExtraData
=ErrorMessage
, File
=self
.MetaFile
)
1174 if Item
not in SortedLibraryList
:
1175 SortedLibraryList
.append(Item
)
1178 # Build the list of constructor and destructir names
1179 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
1181 SortedLibraryList
.reverse()
1182 return SortedLibraryList
1185 ## Override PCD setting (type, value, ...)
1187 # @param ToPcd The PCD to be overrided
1188 # @param FromPcd The PCD overrideing from
1190 def _OverridePcd(self
, ToPcd
, FromPcd
, Module
=""):
1192 # in case there's PCDs coming from FDF file, which have no type given.
1193 # at this point, ToPcd.Type has the type found from dependent
1197 if ToPcd
.Pending
and FromPcd
.Type
not in [None, '']:
1198 ToPcd
.Type
= FromPcd
.Type
1199 elif (ToPcd
.Type
not in [None, '']) and (FromPcd
.Type
not in [None, ''])\
1200 and (ToPcd
.Type
!= FromPcd
.Type
) and (ToPcd
.Type
in FromPcd
.Type
):
1201 if ToPcd
.Type
.strip() == "DynamicEx":
1202 ToPcd
.Type
= FromPcd
.Type
1203 elif ToPcd
.Type
not in [None, ''] and FromPcd
.Type
not in [None, ''] \
1204 and ToPcd
.Type
!= FromPcd
.Type
:
1205 EdkLogger
.error("build", OPTION_CONFLICT
, "Mismatched PCD type",
1206 ExtraData
="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
1207 % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
,
1208 ToPcd
.Type
, Module
, FromPcd
.Type
),
1211 if FromPcd
.MaxDatumSize
not in [None, '']:
1212 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
1213 if FromPcd
.DefaultValue
not in [None, '']:
1214 ToPcd
.DefaultValue
= FromPcd
.DefaultValue
1215 if FromPcd
.TokenValue
not in [None, '']:
1216 ToPcd
.TokenValue
= FromPcd
.TokenValue
1217 if FromPcd
.MaxDatumSize
not in [None, '']:
1218 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
1219 if FromPcd
.DatumType
not in [None, '']:
1220 ToPcd
.DatumType
= FromPcd
.DatumType
1221 if FromPcd
.SkuInfoList
not in [None, '', []]:
1222 ToPcd
.SkuInfoList
= FromPcd
.SkuInfoList
1224 # check the validation of datum
1225 IsValid
, Cause
= CheckPcdDatum(ToPcd
.DatumType
, ToPcd
.DefaultValue
)
1227 EdkLogger
.error('build', FORMAT_INVALID
, Cause
, File
=self
.MetaFile
,
1228 ExtraData
="%s.%s" % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
))
1230 if ToPcd
.DatumType
== "VOID*" and ToPcd
.MaxDatumSize
in ['', None]:
1231 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "No MaxDatumSize specified for PCD %s.%s" \
1232 % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
))
1233 Value
= ToPcd
.DefaultValue
1234 if Value
in [None, '']:
1235 ToPcd
.MaxDatumSize
= 1
1236 elif Value
[0] == 'L':
1237 ToPcd
.MaxDatumSize
= str(len(Value
) * 2)
1238 elif Value
[0] == '{':
1239 ToPcd
.MaxDatumSize
= str(len(Value
.split(',')))
1241 ToPcd
.MaxDatumSize
= str(len(Value
))
1243 # apply default SKU for dynamic PCDS if specified one is not available
1244 if (ToPcd
.Type
in PCD_DYNAMIC_TYPE_LIST
or ToPcd
.Type
in PCD_DYNAMIC_EX_TYPE_LIST
) \
1245 and ToPcd
.SkuInfoList
in [None, {}, '']:
1246 if self
.Platform
.SkuName
in self
.Platform
.SkuIds
:
1247 SkuName
= self
.Platform
.SkuName
1250 ToPcd
.SkuInfoList
= {
1251 SkuName
: SkuInfoClass(SkuName
, self
.Platform
.SkuIds
[SkuName
], '', '', '', '', '', ToPcd
.DefaultValue
)
1254 ## Apply PCD setting defined platform to a module
1256 # @param Module The module from which the PCD setting will be overrided
1258 # @retval PCD_list The list PCDs with settings from platform
1260 def ApplyPcdSetting(self
, Module
, Pcds
):
1261 # for each PCD in module
1262 for Name
,Guid
in Pcds
:
1263 PcdInModule
= Pcds
[Name
,Guid
]
1264 # find out the PCD setting in platform
1265 if (Name
,Guid
) in self
.Platform
.Pcds
:
1266 PcdInPlatform
= self
.Platform
.Pcds
[Name
,Guid
]
1268 PcdInPlatform
= None
1269 # then override the settings if any
1270 self
._OverridePcd
(PcdInModule
, PcdInPlatform
, Module
)
1271 # resolve the VariableGuid value
1272 for SkuId
in PcdInModule
.SkuInfoList
:
1273 Sku
= PcdInModule
.SkuInfoList
[SkuId
]
1274 if Sku
.VariableGuid
== '': continue
1275 Sku
.VariableGuidValue
= GuidValue(Sku
.VariableGuid
, self
.PackageList
)
1276 if Sku
.VariableGuidValue
== None:
1277 PackageList
= "\n\t".join([str(P
) for P
in self
.PackageList
])
1280 RESOURCE_NOT_AVAILABLE
,
1281 "Value of GUID [%s] is not found in" % Sku
.VariableGuid
,
1282 ExtraData
=PackageList
+ "\n\t(used with %s.%s from module %s)" \
1283 % (Guid
, Name
, str(Module
)),
1287 # override PCD settings with module specific setting
1288 if Module
in self
.Platform
.Modules
:
1289 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1290 for Key
in PlatformModule
.Pcds
:
1292 self
._OverridePcd
(Pcds
[Key
], PlatformModule
.Pcds
[Key
], Module
)
1293 return Pcds
.values()
1295 ## Resolve library names to library modules
1297 # (for R8.x modules)
1299 # @param Module The module from which the library names will be resolved
1301 # @retval library_list The list of library modules
1303 def ResolveLibraryReference(self
, Module
):
1304 EdkLogger
.verbose("")
1305 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
1306 LibraryConsumerList
= [Module
]
1308 # "CompilerStub" is a must for R8 modules
1309 if Module
.Libraries
:
1310 Module
.Libraries
.append("CompilerStub")
1312 while len(LibraryConsumerList
) > 0:
1313 M
= LibraryConsumerList
.pop()
1314 for LibraryName
in M
.Libraries
:
1315 Library
= self
.Platform
.LibraryClasses
[LibraryName
, ':dummy:']
1317 for Key
in self
.Platform
.LibraryClasses
.data
.keys():
1318 if LibraryName
.upper() == Key
.upper():
1319 Library
= self
.Platform
.LibraryClasses
[Key
, ':dummy:']
1322 EdkLogger
.warn("build", "Library [%s] is not found" % LibraryName
, File
=str(M
),
1323 ExtraData
="\t%s [%s]" % (str(Module
), self
.Arch
))
1326 if Library
not in LibraryList
:
1327 LibraryList
.append(Library
)
1328 LibraryConsumerList
.append(Library
)
1329 EdkLogger
.verbose("\t" + LibraryName
+ " : " + str(Library
) + ' ' + str(type(Library
)))
1332 ## Calculate the priority value of the build option
1334 # @param Key Build option definition contain: TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
1336 # @retval Value Priority value based on the priority list.
1338 def CalculatePriorityValue(self
, Key
):
1339 Target
, ToolChain
, Arch
, CommandType
, Attr
= Key
.split('_')
1340 PriorityValue
= 0x11111
1342 PriorityValue
&= 0x01111
1343 if ToolChain
== "*":
1344 PriorityValue
&= 0x10111
1346 PriorityValue
&= 0x11011
1347 if CommandType
== "*":
1348 PriorityValue
&= 0x11101
1350 PriorityValue
&= 0x11110
1352 return self
.PrioList
["0x%0.5x"%PriorityValue
]
1355 ## Expand * in build option key
1357 # @param Options Options to be expanded
1359 # @retval options Options expanded
1361 def _ExpandBuildOption(self
, Options
, ModuleStyle
=None):
1368 # Construct a list contain the build options which need override.
1372 # Key[0] -- tool family
1373 # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
1375 if Key
[0] == self
.BuildRuleFamily
:
1376 Target
, ToolChain
, Arch
, CommandType
, Attr
= Key
[1].split('_')
1377 if Target
== self
.BuildTarget
or Target
== "*":
1378 if ToolChain
== self
.ToolChain
or ToolChain
== "*":
1379 if Arch
== self
.Arch
or Arch
== "*":
1380 if Options
[Key
].startswith("="):
1381 if OverrideList
.get(Key
[1]) != None:
1382 OverrideList
.pop(Key
[1])
1383 OverrideList
[Key
[1]] = Options
[Key
]
1386 # Use the highest priority value.
1388 if (len(OverrideList
) >= 2):
1389 KeyList
= OverrideList
.keys()
1390 for Index
in range(len(KeyList
)):
1391 NowKey
= KeyList
[Index
]
1392 Target1
, ToolChain1
, Arch1
, CommandType1
, Attr1
= NowKey
.split("_")
1393 for Index1
in range(len(KeyList
) - Index
- 1):
1394 NextKey
= KeyList
[Index1
+ Index
+ 1]
1396 # Compare two Key, if one is included by another, choose the higher priority one
1398 Target2
, ToolChain2
, Arch2
, CommandType2
, Attr2
= NextKey
.split("_")
1399 if Target1
== Target2
or Target1
== "*" or Target2
== "*":
1400 if ToolChain1
== ToolChain2
or ToolChain1
== "*" or ToolChain2
== "*":
1401 if Arch1
== Arch2
or Arch1
== "*" or Arch2
== "*":
1402 if CommandType1
== CommandType2
or CommandType1
== "*" or CommandType2
== "*":
1403 if Attr1
== Attr2
or Attr1
== "*" or Attr2
== "*":
1404 if self
.CalculatePriorityValue(NowKey
) > self
.CalculatePriorityValue(NextKey
):
1405 if Options
.get((self
.BuildRuleFamily
, NextKey
)) != None:
1406 Options
.pop((self
.BuildRuleFamily
, NextKey
))
1408 if Options
.get((self
.BuildRuleFamily
, NowKey
)) != None:
1409 Options
.pop((self
.BuildRuleFamily
, NowKey
))
1413 if ModuleStyle
!= None and len (Key
) > 2:
1414 # Check Module style is EDK or EDKII.
1415 # Only append build option for the matched style module.
1416 if ModuleStyle
== EDK_NAME
and Key
[2] != EDK_NAME
:
1418 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
1421 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
1422 # if tool chain family doesn't match, skip it
1423 if Tool
in self
.ToolDefinition
and Family
!= "":
1424 FamilyIsNull
= False
1425 if self
.ToolDefinition
[Tool
].get(TAB_TOD_DEFINES_BUILDRULEFAMILY
, "") != "":
1426 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_BUILDRULEFAMILY
]:
1428 elif Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
1431 # expand any wildcard
1432 if Target
== "*" or Target
== self
.BuildTarget
:
1433 if Tag
== "*" or Tag
== self
.ToolChain
:
1434 if Arch
== "*" or Arch
== self
.Arch
:
1435 if Tool
not in BuildOptions
:
1436 BuildOptions
[Tool
] = {}
1437 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
]:
1438 BuildOptions
[Tool
][Attr
] = Options
[Key
]
1440 # append options for the same tool
1441 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
1442 # Build Option Family has been checked, which need't to be checked again for family.
1443 if FamilyMatch
or FamilyIsNull
:
1447 if ModuleStyle
!= None and len (Key
) > 2:
1448 # Check Module style is EDK or EDKII.
1449 # Only append build option for the matched style module.
1450 if ModuleStyle
== EDK_NAME
and Key
[2] != EDK_NAME
:
1452 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
1455 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
1456 # if tool chain family doesn't match, skip it
1457 if Tool
not in self
.ToolDefinition
or Family
=="":
1459 # option has been added before
1460 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
1463 # expand any wildcard
1464 if Target
== "*" or Target
== self
.BuildTarget
:
1465 if Tag
== "*" or Tag
== self
.ToolChain
:
1466 if Arch
== "*" or Arch
== self
.Arch
:
1467 if Tool
not in BuildOptions
:
1468 BuildOptions
[Tool
] = {}
1469 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
]:
1470 BuildOptions
[Tool
][Attr
] = Options
[Key
]
1472 # append options for the same tool
1473 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
1476 ## Append build options in platform to a module
1478 # @param Module The module to which the build options will be appened
1480 # @retval options The options appended with build options in platform
1482 def ApplyBuildOption(self
, Module
):
1483 # Get the different options for the different style module
1484 if Module
.AutoGenVersion
< 0x00010005:
1485 PlatformOptions
= self
.EdkBuildOption
1487 PlatformOptions
= self
.EdkIIBuildOption
1488 ModuleOptions
= self
._ExpandBuildOption
(Module
.BuildOptions
)
1489 if Module
in self
.Platform
.Modules
:
1490 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1491 PlatformModuleOptions
= self
._ExpandBuildOption
(PlatformModule
.BuildOptions
)
1493 PlatformModuleOptions
= {}
1495 AllTools
= set(ModuleOptions
.keys() + PlatformOptions
.keys() + PlatformModuleOptions
.keys() + self
.ToolDefinition
.keys())
1497 for Tool
in AllTools
:
1498 if Tool
not in BuildOptions
:
1499 BuildOptions
[Tool
] = {}
1501 for Options
in [self
.ToolDefinition
, ModuleOptions
, PlatformOptions
, PlatformModuleOptions
]:
1502 if Tool
not in Options
:
1504 for Attr
in Options
[Tool
]:
1505 Value
= Options
[Tool
][Attr
]
1506 if Attr
not in BuildOptions
[Tool
]:
1507 BuildOptions
[Tool
][Attr
] = ""
1508 # check if override is indicated
1509 if Value
.startswith('='):
1510 BuildOptions
[Tool
][Attr
] = Value
[1:]
1512 BuildOptions
[Tool
][Attr
] += " " + Value
1513 if Module
.AutoGenVersion
< 0x00010005 and self
.Workspace
.UniFlag
!= None:
1515 # Override UNI flag only for EDK module.
1517 if 'BUILD' not in BuildOptions
:
1518 BuildOptions
['BUILD'] = {}
1519 BuildOptions
['BUILD']['FLAGS'] = self
.Workspace
.UniFlag
1522 Platform
= property(_GetPlatform
)
1523 Name
= property(_GetName
)
1524 Guid
= property(_GetGuid
)
1525 Version
= property(_GetVersion
)
1527 OutputDir
= property(_GetOutputDir
)
1528 BuildDir
= property(_GetBuildDir
)
1529 MakeFileDir
= property(_GetMakeFileDir
)
1530 FdfFile
= property(_GetFdfFile
)
1532 PcdTokenNumber
= property(_GetPcdTokenNumbers
) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
1533 DynamicPcdList
= property(_GetDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1534 NonDynamicPcdList
= property(_GetNonDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1535 PackageList
= property(_GetPackageList
)
1537 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
1538 ToolDefinitionFile
= property(_GetToolDefFile
) # toolcode : lib path
1539 ToolChainFamily
= property(_GetToolChainFamily
)
1540 BuildRuleFamily
= property(_GetBuildRuleFamily
)
1541 BuildOption
= property(_GetBuildOptions
) # toolcode : option
1542 EdkBuildOption
= property(_GetEdkBuildOptions
) # edktoolcode : option
1543 EdkIIBuildOption
= property(_GetEdkIIBuildOptions
) # edkiitoolcode : option
1545 BuildCommand
= property(_GetBuildCommand
)
1546 BuildRule
= property(_GetBuildRule
)
1547 ModuleAutoGenList
= property(_GetModuleAutoGenList
)
1548 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
1550 ## ModuleAutoGen class
1552 # This class encapsules the AutoGen behaviors for the build tools. In addition to
1553 # the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according
1554 # to the [depex] section in module's inf file.
1556 class ModuleAutoGen(AutoGen
):
1557 ## The real constructor of ModuleAutoGen
1559 # This method is not supposed to be called by users of ModuleAutoGen. It's
1560 # only used by factory method __new__() to do real initialization work for an
1561 # object of ModuleAutoGen
1563 # @param Workspace EdkIIWorkspaceBuild object
1564 # @param ModuleFile The path of module file
1565 # @param Target Build target (DEBUG, RELEASE)
1566 # @param Toolchain Name of tool chain
1567 # @param Arch The arch the module supports
1568 # @param PlatformFile Platform meta-file
1570 def _Init(self
, Workspace
, ModuleFile
, Target
, Toolchain
, Arch
, PlatformFile
):
1571 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen module [%s] [%s]" % (ModuleFile
, Arch
))
1572 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (ModuleFile
, Arch
, Toolchain
, Target
)
1574 self
.Workspace
= Workspace
1575 self
.WorkspaceDir
= Workspace
.WorkspaceDir
1577 self
.MetaFile
= ModuleFile
1578 self
.PlatformInfo
= PlatformAutoGen(Workspace
, PlatformFile
, Target
, Toolchain
, Arch
)
1579 # check if this module is employed by active platform
1580 if not self
.PlatformInfo
.ValidModule(self
.MetaFile
):
1581 EdkLogger
.verbose("Module [%s] for [%s] is not employed by active platform\n" \
1582 % (self
.MetaFile
, Arch
))
1585 self
.SourceDir
= self
.MetaFile
.SubDir
1586 self
.SourceOverrideDir
= None
1587 # use overrided path defined in DSC file
1588 if self
.MetaFile
.Key
in GlobalData
.gOverrideDir
:
1589 self
.SourceOverrideDir
= GlobalData
.gOverrideDir
[self
.MetaFile
.Key
]
1591 self
.ToolChain
= Toolchain
1592 self
.BuildTarget
= Target
1594 self
.ToolChainFamily
= self
.PlatformInfo
.ToolChainFamily
1595 self
.BuildRuleFamily
= self
.PlatformInfo
.BuildRuleFamily
1597 self
.IsMakeFileCreated
= False
1598 self
.IsCodeFileCreated
= False
1600 self
.BuildDatabase
= self
.Workspace
.BuildDatabase
1605 self
._Version
= None
1606 self
._ModuleType
= None
1607 self
._ComponentType
= None
1608 self
._PcdIsDriver
= None
1609 self
._AutoGenVersion
= None
1610 self
._LibraryFlag
= None
1611 self
._CustomMakefile
= None
1614 self
._BuildDir
= None
1615 self
._OutputDir
= None
1616 self
._DebugDir
= None
1617 self
._MakeFileDir
= None
1619 self
._IncludePathList
= None
1620 self
._AutoGenFileList
= None
1621 self
._UnicodeFileList
= None
1622 self
._SourceFileList
= None
1623 self
._ObjectFileList
= None
1624 self
._BinaryFileList
= None
1626 self
._DependentPackageList
= None
1627 self
._DependentLibraryList
= None
1628 self
._LibraryAutoGenList
= None
1629 self
._DerivedPackageList
= None
1630 self
._ModulePcdList
= None
1631 self
._LibraryPcdList
= None
1632 self
._GuidList
= None
1633 self
._ProtocolList
= None
1634 self
._PpiList
= None
1635 self
._DepexList
= None
1636 self
._DepexExpressionList
= None
1637 self
._BuildOption
= None
1638 self
._BuildTargets
= None
1639 self
._IntroBuildTargetList
= None
1640 self
._FinalBuildTargetList
= None
1641 self
._FileTypes
= None
1642 self
._BuildRules
= None
1647 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
1649 # Macros could be used in build_rule.txt (also Makefile)
1650 def _GetMacros(self
):
1651 if self
._Macro
== None:
1652 self
._Macro
= sdict()
1653 self
._Macro
["WORKSPACE" ] = self
.WorkspaceDir
1654 self
._Macro
["MODULE_NAME" ] = self
.Name
1655 self
._Macro
["MODULE_GUID" ] = self
.Guid
1656 self
._Macro
["MODULE_VERSION" ] = self
.Version
1657 self
._Macro
["MODULE_TYPE" ] = self
.ModuleType
1658 self
._Macro
["MODULE_FILE" ] = str(self
.MetaFile
)
1659 self
._Macro
["MODULE_FILE_BASE_NAME" ] = self
.MetaFile
.BaseName
1660 self
._Macro
["MODULE_RELATIVE_DIR" ] = self
.SourceDir
1661 self
._Macro
["MODULE_DIR" ] = self
.SourceDir
1663 self
._Macro
["BASE_NAME" ] = self
.Name
1665 self
._Macro
["ARCH" ] = self
.Arch
1666 self
._Macro
["TOOLCHAIN" ] = self
.ToolChain
1667 self
._Macro
["TOOLCHAIN_TAG" ] = self
.ToolChain
1668 self
._Macro
["TARGET" ] = self
.BuildTarget
1670 self
._Macro
["BUILD_DIR" ] = self
.PlatformInfo
.BuildDir
1671 self
._Macro
["BIN_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
1672 self
._Macro
["LIB_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
1673 self
._Macro
["MODULE_BUILD_DIR" ] = self
.BuildDir
1674 self
._Macro
["OUTPUT_DIR" ] = self
.OutputDir
1675 self
._Macro
["DEBUG_DIR" ] = self
.DebugDir
1678 ## Return the module build data object
1679 def _GetModule(self
):
1680 if self
._Module
== None:
1681 self
._Module
= self
.Workspace
.BuildDatabase
[self
.MetaFile
, self
.Arch
]
1684 ## Return the module name
1685 def _GetBaseName(self
):
1686 return self
.Module
.BaseName
1688 ## Return the module SourceOverridePath
1689 def _GetSourceOverridePath(self
):
1690 return self
.Module
.SourceOverridePath
1692 ## Return the module meta-file GUID
1694 return self
.Module
.Guid
1696 ## Return the module version
1697 def _GetVersion(self
):
1698 return self
.Module
.Version
1700 ## Return the module type
1701 def _GetModuleType(self
):
1702 return self
.Module
.ModuleType
1704 ## Return the component type (for R8.x style of module)
1705 def _GetComponentType(self
):
1706 return self
.Module
.ComponentType
1708 ## Return the build type
1709 def _GetBuildType(self
):
1710 return self
.Module
.BuildType
1712 ## Return the PCD_IS_DRIVER setting
1713 def _GetPcdIsDriver(self
):
1714 return self
.Module
.PcdIsDriver
1716 ## Return the autogen version, i.e. module meta-file version
1717 def _GetAutoGenVersion(self
):
1718 return self
.Module
.AutoGenVersion
1720 ## Check if the module is library or not
1721 def _IsLibrary(self
):
1722 if self
._LibraryFlag
== None:
1723 if self
.Module
.LibraryClass
!= None and self
.Module
.LibraryClass
!= []:
1724 self
._LibraryFlag
= True
1726 self
._LibraryFlag
= False
1727 return self
._LibraryFlag
1729 ## Return the directory to store intermediate files of the module
1730 def _GetBuildDir(self
):
1731 if self
._BuildDir
== None:
1732 self
._BuildDir
= path
.join(
1733 self
.PlatformInfo
.BuildDir
,
1736 self
.MetaFile
.BaseName
1738 CreateDirectory(self
._BuildDir
)
1739 return self
._BuildDir
1741 ## Return the directory to store the intermediate object files of the mdoule
1742 def _GetOutputDir(self
):
1743 if self
._OutputDir
== None:
1744 self
._OutputDir
= path
.join(self
.BuildDir
, "OUTPUT")
1745 CreateDirectory(self
._OutputDir
)
1746 return self
._OutputDir
1748 ## Return the directory to store auto-gened source files of the mdoule
1749 def _GetDebugDir(self
):
1750 if self
._DebugDir
== None:
1751 self
._DebugDir
= path
.join(self
.BuildDir
, "DEBUG")
1752 CreateDirectory(self
._DebugDir
)
1753 return self
._DebugDir
1755 ## Return the path of custom file
1756 def _GetCustomMakefile(self
):
1757 if self
._CustomMakefile
== None:
1758 self
._CustomMakefile
= {}
1759 for Type
in self
.Module
.CustomMakefile
:
1760 if Type
in gMakeTypeMap
:
1761 MakeType
= gMakeTypeMap
[Type
]
1764 if self
.SourceOverrideDir
!= None:
1765 File
= os
.path
.join(self
.SourceOverrideDir
, self
.Module
.CustomMakefile
[Type
])
1766 if not os
.path
.exists(File
):
1767 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
1769 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
1770 self
._CustomMakefile
[MakeType
] = File
1771 return self
._CustomMakefile
1773 ## Return the directory of the makefile
1775 # @retval string The directory string of module's makefile
1777 def _GetMakeFileDir(self
):
1778 return self
.BuildDir
1780 ## Return build command string
1782 # @retval string Build command string
1784 def _GetBuildCommand(self
):
1785 return self
.PlatformInfo
.BuildCommand
1787 ## Get object list of all packages the module and its dependent libraries belong to
1789 # @retval list The list of package object
1791 def _GetDerivedPackageList(self
):
1793 for M
in [self
.Module
] + self
.DependentLibraryList
:
1794 for Package
in M
.Packages
:
1795 if Package
in PackageList
:
1797 PackageList
.append(Package
)
1800 ## Merge dependency expression
1802 # @retval list The token list of the dependency expression after parsed
1804 def _GetDepexTokenList(self
):
1805 if self
._DepexList
== None:
1806 self
._DepexList
= {}
1807 if self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
1808 return self
._DepexList
1810 self
._DepexList
[self
.ModuleType
] = []
1812 for ModuleType
in self
._DepexList
:
1813 DepexList
= self
._DepexList
[ModuleType
]
1815 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
1817 for M
in [self
.Module
] + self
.DependentLibraryList
:
1819 for D
in M
.Depex
[self
.Arch
, ModuleType
]:
1821 DepexList
.append('AND')
1822 DepexList
.append('(')
1824 if DepexList
[-1] == 'END': # no need of a END at this time
1826 DepexList
.append(')')
1829 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexList
))
1830 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
1832 if len(DepexList
) > 0:
1833 EdkLogger
.verbose('')
1834 return self
._DepexList
1836 ## Merge dependency expression
1838 # @retval list The token list of the dependency expression after parsed
1840 def _GetDepexExpressionTokenList(self
):
1841 if self
._DepexExpressionList
== None:
1842 self
._DepexExpressionList
= {}
1843 if self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
1844 return self
._DepexExpressionList
1846 self
._DepexExpressionList
[self
.ModuleType
] = ''
1848 for ModuleType
in self
._DepexExpressionList
:
1849 DepexExpressionList
= self
._DepexExpressionList
[ModuleType
]
1851 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
1853 for M
in [self
.Module
] + self
.DependentLibraryList
:
1855 for D
in M
.DepexExpression
[self
.Arch
, ModuleType
]:
1856 if DepexExpressionList
!= '':
1857 DepexExpressionList
+= ' AND '
1858 DepexExpressionList
+= '('
1859 DepexExpressionList
+= D
1860 DepexExpressionList
= DepexExpressionList
.rstrip('END').strip()
1861 DepexExpressionList
+= ')'
1864 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexExpressionList
))
1865 if 'BEFORE' in DepexExpressionList
or 'AFTER' in DepexExpressionList
:
1867 if len(DepexExpressionList
) > 0:
1868 EdkLogger
.verbose('')
1869 self
._DepexExpressionList
[ModuleType
] = DepexExpressionList
1870 return self
._DepexExpressionList
1872 ## Return the list of specification version required for the module
1874 # @retval list The list of specification defined in module file
1876 def _GetSpecification(self
):
1877 return self
.Module
.Specification
1879 ## Tool option for the module build
1881 # @param PlatformInfo The object of PlatformBuildInfo
1882 # @retval dict The dict containing valid options
1884 def _GetModuleBuildOption(self
):
1885 if self
._BuildOption
== None:
1886 self
._BuildOption
= self
.PlatformInfo
.ApplyBuildOption(self
.Module
)
1887 return self
._BuildOption
1889 ## Return a list of files which can be built from source
1891 # What kind of files can be built is determined by build rules in
1892 # $(WORKSPACE)/Conf/build_rule.txt and toolchain family.
1894 def _GetSourceFileList(self
):
1895 if self
._SourceFileList
== None:
1896 self
._SourceFileList
= []
1897 for F
in self
.Module
.Sources
:
1899 if F
.TagName
not in ("", "*", self
.ToolChain
):
1900 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "The toolchain [%s] for processing file [%s] is found, "
1901 "but [%s] is needed" % (F
.TagName
, str(F
), self
.ToolChain
))
1903 # match tool chain family
1904 if F
.ToolChainFamily
not in ("", "*", self
.ToolChainFamily
):
1907 "The file [%s] must be built by tools of [%s], " \
1908 "but current toolchain family is [%s]" \
1909 % (str(F
), F
.ToolChainFamily
, self
.ToolChainFamily
))
1912 # add the file path into search path list for file including
1913 if F
.Dir
not in self
.IncludePathList
and self
.AutoGenVersion
>= 0x00010005:
1914 self
.IncludePathList
.insert(0, F
.Dir
)
1915 self
._SourceFileList
.append(F
)
1916 self
._ApplyBuildRule
(F
, TAB_UNKNOWN_FILE
)
1917 return self
._SourceFileList
1919 ## Return the list of unicode files
1920 def _GetUnicodeFileList(self
):
1921 if self
._UnicodeFileList
== None:
1922 if TAB_UNICODE_FILE
in self
.FileTypes
:
1923 self
._UnicodeFileList
= self
.FileTypes
[TAB_UNICODE_FILE
]
1925 self
._UnicodeFileList
= []
1926 return self
._UnicodeFileList
1928 ## Return a list of files which can be built from binary
1930 # "Build" binary files are just to copy them to build directory.
1932 # @retval list The list of files which can be built later
1934 def _GetBinaryFiles(self
):
1935 if self
._BinaryFileList
== None:
1936 self
._BinaryFileList
= []
1937 for F
in self
.Module
.Binaries
:
1938 if F
.Target
not in ['COMMON', '*'] and F
.Target
!= self
.BuildTarget
:
1940 self
._BinaryFileList
.append(F
)
1941 self
._ApplyBuildRule
(F
, F
.Type
)
1942 return self
._BinaryFileList
1944 def _GetBuildRules(self
):
1945 if self
._BuildRules
== None:
1947 BuildRuleDatabase
= self
.PlatformInfo
.BuildRule
1948 for Type
in BuildRuleDatabase
.FileTypeList
:
1949 #first try getting build rule by BuildRuleFamily
1950 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.BuildRuleFamily
]
1952 # build type is always module type, but ...
1953 if self
.ModuleType
!= self
.BuildType
:
1954 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.BuildRuleFamily
]
1955 #second try getting build rule by ToolChainFamily
1957 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.ToolChainFamily
]
1959 # build type is always module type, but ...
1960 if self
.ModuleType
!= self
.BuildType
:
1961 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.ToolChainFamily
]
1964 RuleObject
= RuleObject
.Instantiate(self
.Macros
)
1965 BuildRules
[Type
] = RuleObject
1966 for Ext
in RuleObject
.SourceFileExtList
:
1967 BuildRules
[Ext
] = RuleObject
1968 self
._BuildRules
= BuildRules
1969 return self
._BuildRules
1971 def _ApplyBuildRule(self
, File
, FileType
):
1972 if self
._BuildTargets
== None:
1973 self
._IntroBuildTargetList
= set()
1974 self
._FinalBuildTargetList
= set()
1975 self
._BuildTargets
= {}
1976 self
._FileTypes
= {}
1982 while Index
< len(SourceList
):
1983 Source
= SourceList
[Index
]
1987 CreateDirectory(Source
.Dir
)
1989 if File
.IsBinary
and File
== Source
and self
._BinaryFileList
!= None and File
in self
._BinaryFileList
:
1990 RuleObject
= self
.BuildRules
[TAB_DEFAULT_BINARY_FILE
]
1991 elif FileType
in self
.BuildRules
:
1992 RuleObject
= self
.BuildRules
[FileType
]
1993 elif Source
.Ext
in self
.BuildRules
:
1994 RuleObject
= self
.BuildRules
[Source
.Ext
]
1996 # stop at no more rules
1998 self
._FinalBuildTargetList
.add(LastTarget
)
2001 FileType
= RuleObject
.SourceFileType
2002 if FileType
not in self
._FileTypes
:
2003 self
._FileTypes
[FileType
] = set()
2004 self
._FileTypes
[FileType
].add(Source
)
2006 # stop at STATIC_LIBRARY for library
2007 if self
.IsLibrary
and FileType
== TAB_STATIC_LIBRARY
:
2009 self
._FinalBuildTargetList
.add(LastTarget
)
2012 Target
= RuleObject
.Apply(Source
)
2015 self
._FinalBuildTargetList
.add(LastTarget
)
2017 elif not Target
.Outputs
:
2018 # Only do build for target with outputs
2019 self
._FinalBuildTargetList
.add(Target
)
2021 if FileType
not in self
._BuildTargets
:
2022 self
._BuildTargets
[FileType
] = set()
2023 self
._BuildTargets
[FileType
].add(Target
)
2025 if not Source
.IsBinary
and Source
== File
:
2026 self
._IntroBuildTargetList
.add(Target
)
2028 # to avoid cyclic rule
2029 if FileType
in RuleChain
:
2032 RuleChain
.append(FileType
)
2033 SourceList
.extend(Target
.Outputs
)
2035 FileType
= TAB_UNKNOWN_FILE
2037 def _GetTargets(self
):
2038 if self
._BuildTargets
== None:
2039 self
._IntroBuildTargetList
= set()
2040 self
._FinalBuildTargetList
= set()
2041 self
._BuildTargets
= {}
2042 self
._FileTypes
= {}
2044 #TRICK: call _GetSourceFileList to apply build rule for binary files
2045 if self
.SourceFileList
:
2048 #TRICK: call _GetBinaryFileList to apply build rule for binary files
2049 if self
.BinaryFileList
:
2052 return self
._BuildTargets
2054 def _GetIntroTargetList(self
):
2056 return self
._IntroBuildTargetList
2058 def _GetFinalTargetList(self
):
2060 return self
._FinalBuildTargetList
2062 def _GetFileTypes(self
):
2064 return self
._FileTypes
2066 ## Get the list of package object the module depends on
2068 # @retval list The package object list
2070 def _GetDependentPackageList(self
):
2071 return self
.Module
.Packages
2073 ## Return the list of auto-generated code file
2075 # @retval list The list of auto-generated file
2077 def _GetAutoGenFileList(self
):
2078 UniStringAutoGenC
= True
2079 UniStringBinBuffer
= None
2080 if self
.BuildType
== 'UEFI_HII':
2081 UniStringBinBuffer
= StringIO()
2082 UniStringAutoGenC
= False
2083 if self
._AutoGenFileList
== None:
2084 self
._AutoGenFileList
= {}
2085 AutoGenC
= TemplateString()
2086 AutoGenH
= TemplateString()
2087 StringH
= TemplateString()
2088 GenC
.CreateCode(self
, AutoGenC
, AutoGenH
, StringH
, UniStringAutoGenC
, UniStringBinBuffer
)
2089 if str(AutoGenC
) != "" and TAB_C_CODE_FILE
in self
.FileTypes
:
2090 AutoFile
= PathClass(gAutoGenCodeFileName
, self
.DebugDir
)
2091 self
._AutoGenFileList
[AutoFile
] = str(AutoGenC
)
2092 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
2093 if str(AutoGenH
) != "":
2094 AutoFile
= PathClass(gAutoGenHeaderFileName
, self
.DebugDir
)
2095 self
._AutoGenFileList
[AutoFile
] = str(AutoGenH
)
2096 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
2097 if str(StringH
) != "":
2098 AutoFile
= PathClass(gAutoGenStringFileName
% {"module_name":self
.Name
}, self
.DebugDir
)
2099 self
._AutoGenFileList
[AutoFile
] = str(StringH
)
2100 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
2101 if UniStringBinBuffer
!= None and UniStringBinBuffer
.getvalue() != "":
2102 AutoFile
= PathClass(gAutoGenStringFormFileName
% {"module_name":self
.Name
}, self
.OutputDir
)
2103 self
._AutoGenFileList
[AutoFile
] = UniStringBinBuffer
.getvalue()
2104 AutoFile
.IsBinary
= True
2105 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
2106 if UniStringBinBuffer
!= None:
2107 UniStringBinBuffer
.close()
2108 return self
._AutoGenFileList
2110 ## Return the list of library modules explicitly or implicityly used by this module
2111 def _GetLibraryList(self
):
2112 if self
._DependentLibraryList
== None:
2113 # only merge library classes and PCD for non-library module
2115 self
._DependentLibraryList
= []
2117 if self
.AutoGenVersion
< 0x00010005:
2118 self
._DependentLibraryList
= self
.PlatformInfo
.ResolveLibraryReference(self
.Module
)
2120 self
._DependentLibraryList
= self
.PlatformInfo
.ApplyLibraryInstance(self
.Module
)
2121 return self
._DependentLibraryList
2123 ## Get the list of PCDs from current module
2125 # @retval list The list of PCD
2127 def _GetModulePcdList(self
):
2128 if self
._ModulePcdList
== None:
2129 # apply PCD settings from platform
2130 self
._ModulePcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, self
.Module
.Pcds
)
2131 return self
._ModulePcdList
2133 ## Get the list of PCDs from dependent libraries
2135 # @retval list The list of PCD
2137 def _GetLibraryPcdList(self
):
2138 if self
._LibraryPcdList
== None:
2140 if not self
.IsLibrary
:
2141 # get PCDs from dependent libraries
2142 for Library
in self
.DependentLibraryList
:
2143 for Key
in Library
.Pcds
:
2144 # skip duplicated PCDs
2145 if Key
in self
.Module
.Pcds
or Key
in Pcds
:
2147 Pcds
[Key
] = copy
.copy(Library
.Pcds
[Key
])
2148 # apply PCD settings from platform
2149 self
._LibraryPcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, Pcds
)
2151 self
._LibraryPcdList
= []
2152 return self
._LibraryPcdList
2154 ## Get the GUID value mapping
2156 # @retval dict The mapping between GUID cname and its value
2158 def _GetGuidList(self
):
2159 if self
._GuidList
== None:
2160 self
._GuidList
= self
.Module
.Guids
2161 for Library
in self
.DependentLibraryList
:
2162 self
._GuidList
.update(Library
.Guids
)
2163 return self
._GuidList
2165 ## Get the protocol value mapping
2167 # @retval dict The mapping between protocol cname and its value
2169 def _GetProtocolList(self
):
2170 if self
._ProtocolList
== None:
2171 self
._ProtocolList
= self
.Module
.Protocols
2172 for Library
in self
.DependentLibraryList
:
2173 self
._ProtocolList
.update(Library
.Protocols
)
2174 return self
._ProtocolList
2176 ## Get the PPI value mapping
2178 # @retval dict The mapping between PPI cname and its value
2180 def _GetPpiList(self
):
2181 if self
._PpiList
== None:
2182 self
._PpiList
= self
.Module
.Ppis
2183 for Library
in self
.DependentLibraryList
:
2184 self
._PpiList
.update(Library
.Ppis
)
2185 return self
._PpiList
2187 ## Get the list of include search path
2189 # @retval list The list path
2191 def _GetIncludePathList(self
):
2192 if self
._IncludePathList
== None:
2193 self
._IncludePathList
= []
2194 if self
.AutoGenVersion
< 0x00010005:
2195 for Inc
in self
.Module
.Includes
:
2196 if Inc
not in self
._IncludePathList
:
2197 self
._IncludePathList
.append(Inc
)
2199 Inc
= path
.join(Inc
, self
.Arch
.capitalize())
2200 if os
.path
.exists(Inc
) and Inc
not in self
._IncludePathList
:
2201 self
._IncludePathList
.append(Inc
)
2202 # r8 module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
2203 self
._IncludePathList
.append(self
.DebugDir
)
2205 self
._IncludePathList
.append(self
.MetaFile
.Dir
)
2206 self
._IncludePathList
.append(self
.DebugDir
)
2208 for Package
in self
.Module
.Packages
:
2209 PackageDir
= path
.join(self
.WorkspaceDir
, Package
.MetaFile
.Dir
)
2210 if PackageDir
not in self
._IncludePathList
:
2211 self
._IncludePathList
.append(PackageDir
)
2212 for Inc
in Package
.Includes
:
2213 if Inc
not in self
._IncludePathList
:
2214 self
._IncludePathList
.append(str(Inc
))
2215 return self
._IncludePathList
2217 ## Create makefile for the module and its dependent libraries
2219 # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of
2220 # dependent libraries will be created
2222 def CreateMakeFile(self
, CreateLibraryMakeFile
=True):
2223 if self
.IsMakeFileCreated
:
2226 if not self
.IsLibrary
and CreateLibraryMakeFile
:
2227 for LibraryAutoGen
in self
.LibraryAutoGenList
:
2228 LibraryAutoGen
.CreateMakeFile()
2230 if len(self
.CustomMakefile
) == 0:
2231 Makefile
= GenMake
.ModuleMakefile(self
)
2233 Makefile
= GenMake
.CustomMakefile(self
)
2234 if Makefile
.Generate():
2235 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for module %s [%s]" %
2236 (self
.Name
, self
.Arch
))
2238 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for module %s [%s]" %
2239 (self
.Name
, self
.Arch
))
2241 self
.IsMakeFileCreated
= True
2243 ## Create autogen code for the module and its dependent libraries
2245 # @param CreateLibraryCodeFile Flag indicating if or not the code of
2246 # dependent libraries will be created
2248 def CreateCodeFile(self
, CreateLibraryCodeFile
=True):
2249 if self
.IsCodeFileCreated
:
2252 if not self
.IsLibrary
and CreateLibraryCodeFile
:
2253 for LibraryAutoGen
in self
.LibraryAutoGenList
:
2254 LibraryAutoGen
.CreateCodeFile()
2257 IgoredAutoGenList
= []
2259 for File
in self
.AutoGenFileList
:
2260 if GenC
.Generate(File
.Path
, self
.AutoGenFileList
[File
], File
.IsBinary
):
2261 #Ignore R8 AutoGen.c
2262 if self
.AutoGenVersion
< 0x00010005 and File
.Name
== 'AutoGen.c':
2265 AutoGenList
.append(str(File
))
2267 IgoredAutoGenList
.append(str(File
))
2269 # Skip the following code for EDK I inf
2270 if self
.AutoGenVersion
< 0x00010005:
2273 for ModuleType
in self
.DepexList
:
2274 # Ignore empty [depex] section or [depex] section for "USER_DEFINED" module
2275 if len(self
.DepexList
[ModuleType
]) == 0 or ModuleType
== "USER_DEFINED":
2278 Dpx
= GenDepex
.DependencyExpression(self
.DepexList
[ModuleType
], ModuleType
, True)
2279 DpxFile
= gAutoGenDepexFileName
% {"module_name" : self
.Name
}
2281 if Dpx
.Generate(path
.join(self
.OutputDir
, DpxFile
)):
2282 AutoGenList
.append(str(DpxFile
))
2284 IgoredAutoGenList
.append(str(DpxFile
))
2286 if IgoredAutoGenList
== []:
2287 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] files for module %s [%s]" %
2288 (" ".join(AutoGenList
), self
.Name
, self
.Arch
))
2289 elif AutoGenList
== []:
2290 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of [%s] files for module %s [%s]" %
2291 (" ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
2293 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] (skipped %s) files for module %s [%s]" %
2294 (" ".join(AutoGenList
), " ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
2296 self
.IsCodeFileCreated
= True
2299 ## Summarize the ModuleAutoGen objects of all libraries used by this module
2300 def _GetLibraryAutoGenList(self
):
2301 if self
._LibraryAutoGenList
== None:
2302 self
._LibraryAutoGenList
= []
2303 for Library
in self
.DependentLibraryList
:
2310 self
.PlatformInfo
.MetaFile
2312 if La
not in self
._LibraryAutoGenList
:
2313 self
._LibraryAutoGenList
.append(La
)
2314 for Lib
in La
.CodaTargetList
:
2315 self
._ApplyBuildRule
(Lib
.Target
, TAB_UNKNOWN_FILE
)
2316 return self
._LibraryAutoGenList
2318 Module
= property(_GetModule
)
2319 Name
= property(_GetBaseName
)
2320 Guid
= property(_GetGuid
)
2321 Version
= property(_GetVersion
)
2322 ModuleType
= property(_GetModuleType
)
2323 ComponentType
= property(_GetComponentType
)
2324 BuildType
= property(_GetBuildType
)
2325 PcdIsDriver
= property(_GetPcdIsDriver
)
2326 AutoGenVersion
= property(_GetAutoGenVersion
)
2327 Macros
= property(_GetMacros
)
2328 Specification
= property(_GetSpecification
)
2330 IsLibrary
= property(_IsLibrary
)
2332 BuildDir
= property(_GetBuildDir
)
2333 OutputDir
= property(_GetOutputDir
)
2334 DebugDir
= property(_GetDebugDir
)
2335 MakeFileDir
= property(_GetMakeFileDir
)
2336 CustomMakefile
= property(_GetCustomMakefile
)
2338 IncludePathList
= property(_GetIncludePathList
)
2339 AutoGenFileList
= property(_GetAutoGenFileList
)
2340 UnicodeFileList
= property(_GetUnicodeFileList
)
2341 SourceFileList
= property(_GetSourceFileList
)
2342 BinaryFileList
= property(_GetBinaryFiles
) # FileType : [File List]
2343 Targets
= property(_GetTargets
)
2344 IntroTargetList
= property(_GetIntroTargetList
)
2345 CodaTargetList
= property(_GetFinalTargetList
)
2346 FileTypes
= property(_GetFileTypes
)
2347 BuildRules
= property(_GetBuildRules
)
2349 DependentPackageList
= property(_GetDependentPackageList
)
2350 DependentLibraryList
= property(_GetLibraryList
)
2351 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
2352 DerivedPackageList
= property(_GetDerivedPackageList
)
2354 ModulePcdList
= property(_GetModulePcdList
)
2355 LibraryPcdList
= property(_GetLibraryPcdList
)
2356 GuidList
= property(_GetGuidList
)
2357 ProtocolList
= property(_GetProtocolList
)
2358 PpiList
= property(_GetPpiList
)
2359 DepexList
= property(_GetDepexTokenList
)
2360 DepexExpressionList
= property(_GetDepexExpressionTokenList
)
2361 BuildOption
= property(_GetModuleBuildOption
)
2362 BuildCommand
= property(_GetBuildCommand
)
2364 # This acts like the main() function for the script, unless it is 'import'ed into another script.
2365 if __name__
== '__main__':