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
24 from StringIO
import StringIO
26 from StrGather
import *
27 from BuildEngine
import BuildRule
29 from Common
.BuildToolError
import *
30 from Common
.DataType
import *
31 from Common
.Misc
import *
32 from Common
.String
import *
33 import Common
.GlobalData
as GlobalData
34 from GenFds
.FdfParser
import *
35 from CommonDataClass
.CommonClass
import SkuInfoClass
36 from Workspace
.BuildClassObject
import *
38 ## Regular expression for splitting Dependency Expression stirng into tokens
39 gDepexTokenPattern
= re
.compile("(\(|\)|\w+| \S+\.inf)")
41 ## Mapping Makefile type
42 gMakeTypeMap
= {"MSFT":"nmake", "GCC":"gmake"}
45 ## Build rule configuration file
46 gBuildRuleFile
= 'Conf/build_rule.txt'
48 ## default file name for AutoGen
49 gAutoGenCodeFileName
= "AutoGen.c"
50 gAutoGenHeaderFileName
= "AutoGen.h"
51 gAutoGenStringFileName
= "%(module_name)sStrDefs.h"
52 gAutoGenStringFormFileName
= "%(module_name)sStrDefs.hpk"
53 gAutoGenDepexFileName
= "%(module_name)s.depex"
55 ## Base class for AutoGen
57 # This class just implements the cache mechanism of AutoGen objects.
59 class AutoGen(object):
60 # database to maintain the objects of xxxAutoGen
61 _CACHE_
= {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}
65 # @param Class class object of real AutoGen class
66 # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
67 # @param Workspace Workspace directory or WorkspaceAutoGen object
68 # @param MetaFile The path of meta file
69 # @param Target Build target
70 # @param Toolchain Tool chain name
71 # @param Arch Target arch
72 # @param *args The specific class related parameters
73 # @param **kwargs The specific class related dict parameters
75 def __new__(Class
, Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
76 # check if the object has been created
77 Key
= (Target
, Toolchain
)
78 if Key
not in Class
._CACHE
_ or Arch
not in Class
._CACHE
_[Key
] \
79 or MetaFile
not in Class
._CACHE
_[Key
][Arch
]:
80 AutoGenObject
= super(AutoGen
, Class
).__new
__(Class
)
81 # call real constructor
82 if not AutoGenObject
._Init
(Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
84 if Key
not in Class
._CACHE
_:
85 Class
._CACHE
_[Key
] = {}
86 if Arch
not in Class
._CACHE
_[Key
]:
87 Class
._CACHE
_[Key
][Arch
] = {}
88 Class
._CACHE
_[Key
][Arch
][MetaFile
] = AutoGenObject
90 AutoGenObject
= Class
._CACHE
_[Key
][Arch
][MetaFile
]
96 # The file path of platform file will be used to represent hash value of this object
98 # @retval int Hash value of the file path of platform file
101 return hash(self
.MetaFile
)
105 # The file path of platform file will be used to represent this object
107 # @retval string String of platform file path
110 return str(self
.MetaFile
)
113 def __eq__(self
, Other
):
114 return Other
and self
.MetaFile
== Other
116 ## Workspace AutoGen class
118 # This class is used mainly to control the whole platform build for different
119 # architecture. This class will generate top level makefile.
121 class WorkspaceAutoGen(AutoGen
):
122 ## Real constructor of WorkspaceAutoGen
124 # This method behaves the same as __init__ except that it needs explict invoke
125 # (in super class's __new__ method)
127 # @param WorkspaceDir Root directory of workspace
128 # @param ActivePlatform Meta-file of active platform
129 # @param Target Build target
130 # @param Toolchain Tool chain name
131 # @param ArchList List of architecture of current build
132 # @param MetaFileDb Database containing meta-files
133 # @param BuildConfig Configuration of build
134 # @param ToolDefinition Tool chain definitions
135 # @param FlashDefinitionFile File of flash definition
136 # @param Fds FD list to be generated
137 # @param Fvs FV list to be generated
138 # @param SkuId SKU id from command line
140 def _Init(self
, WorkspaceDir
, ActivePlatform
, Target
, Toolchain
, ArchList
, MetaFileDb
,
141 BuildConfig
, ToolDefinition
, FlashDefinitionFile
='', Fds
=[], Fvs
=[], SkuId
='',
142 ReportFile
=None, ReportType
=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
.ReportFile
= ReportFile
151 self
.ReportType
= ReportType
153 self
.BuildDatabase
= MetaFileDb
154 self
.TargetTxt
= BuildConfig
155 self
.ToolDef
= ToolDefinition
156 self
.FdfFile
= FlashDefinitionFile
157 self
.FdTargetList
= Fds
158 self
.FvTargetList
= Fvs
159 self
.AutoGenObjectList
= []
161 # there's many relative directory operations, so ...
162 os
.chdir(self
.WorkspaceDir
)
164 # parse FDF file to get PCDs in it, if any
165 if self
.FdfFile
!= None and self
.FdfFile
!= '':
166 Fdf
= FdfParser(self
.FdfFile
.Path
)
168 PcdSet
= Fdf
.Profile
.PcdDict
169 ModuleList
= Fdf
.Profile
.InfList
174 # apply SKU and inject PCDs from Flash Definition file
175 for Arch
in self
.ArchList
:
176 Platform
= self
.BuildDatabase
[self
.MetaFile
, Arch
]
177 Platform
.SkuName
= self
.SkuId
178 for Name
, Guid
in PcdSet
:
179 Platform
.AddPcd(Name
, Guid
, PcdSet
[Name
, Guid
])
181 Pa
= PlatformAutoGen(self
, self
.MetaFile
, Target
, Toolchain
, Arch
)
183 # Explicitly collect platform's dynamic PCDs
185 Pa
.CollectPlatformDynamicPcds()
186 self
.AutoGenObjectList
.append(Pa
)
190 for Pcd
in Pa
._DynaPcdList
_ + Pa
._NonDynaPcdList
_:
191 if Pcd
.TokenSpaceGuidCName
not in AllPcds
:
192 AllPcds
[Pcd
.TokenSpaceGuidCName
] = {}
193 if Pcd
.Type
not in AllPcds
[Pcd
.TokenSpaceGuidCName
]:
194 AllPcds
[Pcd
.TokenSpaceGuidCName
][Pcd
.Type
] = []
195 AllPcds
[Pcd
.TokenSpaceGuidCName
][Pcd
.Type
] += [Pcd
]
196 if len(Pcd
.TokenCName
) > MaxLen
:
197 MaxLen
= len(Pcd
.TokenCName
)
199 if self
.ReportFile
<> None:
201 if os
.path
.exists(self
.ReportFile
):
202 os
.remove(self
.ReportFile
)
204 Fd
= open(self
.ReportFile
, "w")
206 Fd
.write ('===============================================================================\n')
207 Fd
.write ('Platform Configuration Database Report\n')
208 Fd
.write ('===============================================================================\n')
209 Fd
.write (' *P - Platform scoped PCD override in DSC file\n')
210 Fd
.write (' *F - Platform scoped PCD override in FDF file\n')
211 Fd
.write (' *M - Module scoped PCD override in DSC file\n')
212 Fd
.write (' *C - Library has a constructor\n')
213 Fd
.write (' *D - Library has a destructor\n')
214 Fd
.write (' *CD - Library has both a constructor and a destructor\n')
215 Fd
.write ('===============================================================================\n')
217 Fd
.write ('===============================================================================\n')
218 Fd
.write ('PLATFORM: %s\n' % (ActivePlatform
.MetaFile
))
219 Fd
.write ('===============================================================================\n')
221 Fd
.write ('%s\n' % (Key
))
222 for Type
in AllPcds
[Key
]:
225 if Type
== 'FixedAtBuild':
227 if Type
== 'PatchableInModule':
229 if Type
== 'FeatureFlag':
231 if Type
== 'Dynamic':
233 if Type
== 'DynamicHii':
236 if Type
== 'DynamicVpd':
239 if Type
== 'DynamicEx':
242 if Type
== 'DynamicExHii':
245 if Type
== 'DynamicExVpd':
248 for Pcd
in AllPcds
[Key
][Type
]:
250 DecDefaultValue
= None
251 for F
in Pa
.Platform
.Modules
.keys():
252 for Package
in Pa
.Platform
.Modules
[F
].M
.Module
.Packages
:
253 if (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, DecType
) in Package
.Pcds
:
254 if DecDefaultValue
== None:
255 DecDefaultValue
= Package
.Pcds
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, DecType
].DefaultValue
257 DscDefaultValue
= None
258 if (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
) in self
.BuildDatabase
.WorkspaceDb
.PlatformList
[0].Pcds
:
259 DscDefaultValue
= self
.BuildDatabase
.WorkspaceDb
.PlatformList
[0].Pcds
[(Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
)].DefaultValue
261 if Pcd
.DatumType
in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
262 if Pcd
.DefaultValue
.strip()[0:2].upper() == '0X':
263 PcdDefaultValueNumber
= int(Pcd
.DefaultValue
.strip(), 16)
265 PcdDefaultValueNumber
= int(Pcd
.DefaultValue
.strip())
267 if DecDefaultValue
== None:
270 if DecDefaultValue
.strip()[0:2].upper() == '0X':
271 DecDefaultValueNumber
= int(DecDefaultValue
.strip(), 16)
273 DecDefaultValueNumber
= int(DecDefaultValue
.strip())
274 DecMatch
= (DecDefaultValueNumber
== PcdDefaultValueNumber
)
276 if DscDefaultValue
== None:
279 if DscDefaultValue
.strip()[0:2].upper() == '0X':
280 DscDefaultValueNumber
= int(DscDefaultValue
.strip(), 16)
282 DscDefaultValueNumber
= int(DscDefaultValue
.strip())
283 DscMatch
= (DscDefaultValueNumber
== PcdDefaultValueNumber
)
285 if DecDefaultValue
== None:
288 DecMatch
= (DecDefaultValue
== Pcd
.DefaultValue
)
290 if DscDefaultValue
== None:
293 DscMatch
= (DscDefaultValue
== Pcd
.DefaultValue
)
296 Fd
.write (' %-*s: %6s %10s = %-22s\n' % (MaxLen
+ 2, Pcd
.TokenCName
, TypeName
, '('+Pcd
.DatumType
+')', Pcd
.DefaultValue
))
299 if (Pcd
.TokenCName
, Key
) in PcdSet
:
300 Fd
.write (' *F %-*s: %6s %10s = %-22s\n' % (MaxLen
+ 2, Pcd
.TokenCName
, TypeName
, '('+Pcd
.DatumType
+')', Pcd
.DefaultValue
))
302 Fd
.write (' *P %-*s: %6s %10s = %-22s\n' % (MaxLen
+ 2, Pcd
.TokenCName
, TypeName
, '('+Pcd
.DatumType
+')', Pcd
.DefaultValue
))
304 for F
in Pa
.Platform
.Modules
.keys():
305 for ModulePcd
in Pa
.Platform
.Modules
[F
].M
.ModulePcdList
+ Pa
.Platform
.Modules
[F
].M
.LibraryPcdList
:
306 if ModulePcd
.TokenSpaceGuidCName
<> Pcd
.TokenSpaceGuidCName
:
308 if ModulePcd
.TokenCName
<> Pcd
.TokenCName
:
310 if Pcd
.DatumType
in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
311 if ModulePcd
.DefaultValue
.strip()[0:2].upper() == '0X':
312 ModulePcdDefaultValueNumber
= int(ModulePcd
.DefaultValue
.strip(), 16)
314 ModulePcdDefaultValueNumber
= int(ModulePcd
.DefaultValue
.strip())
315 Match
= (ModulePcdDefaultValueNumber
== PcdDefaultValueNumber
)
317 Match
= (ModulePcd
.DefaultValue
== Pcd
.DefaultValue
)
320 Fd
.write (' *M %*s = %s\n' % (MaxLen
+ 21, str(F
).split('\\')[-1], ModulePcd
.DefaultValue
))
322 if not DecMatch
and DscMatch
and DecDefaultValue
<> None:
323 Fd
.write (' %*s = %s\n' % (MaxLen
+ 21, 'DEC DEFAULT', DecDefaultValue
))
327 Fd
.write ('===============================================================================\n')
328 Fd
.write ('===============================================================================\n')
330 for F
in Pa
.Platform
.Modules
.keys():
332 Fd
.write ('===============================================================================\n')
333 Fd
.write ('MODULE: %s\n' % (F
))
334 Fd
.write ('===============================================================================\n')
336 Fd
.write ('PLATFORM CONFIGURATION DATABASE\n')
337 Fd
.write ('-------------------------------------------------------------------------------\n')
341 for Type
in AllPcds
[Key
]:
344 if Type
== 'FixedAtBuild':
346 if Type
== 'PatchableInModule':
348 if Type
== 'FeatureFlag':
350 if Type
== 'Dynamic':
352 if Type
== 'DynamicHii':
355 if Type
== 'DynamicVpd':
358 if Type
== 'DynamicEx':
361 if Type
== 'DynamicExHii':
364 if Type
== 'DynamicExVpd':
367 for Pcd
in AllPcds
[Key
][Type
]:
368 for ModulePcd
in Pa
.Platform
.Modules
[F
].M
.ModulePcdList
+ Pa
.Platform
.Modules
[F
].M
.LibraryPcdList
:
369 if ModulePcd
.TokenSpaceGuidCName
<> Pcd
.TokenSpaceGuidCName
:
371 if ModulePcd
.TokenCName
<> Pcd
.TokenCName
:
373 if ModulePcd
.Type
<> Pcd
.Type
:
380 Fd
.write ('%s\n' % (Key
))
383 InfDefaultValue
= ModulePcd
.InfDefaultValue
384 if InfDefaultValue
== '':
385 InfDefaultValue
= None
387 DecDefaultValue
= None
388 for Package
in Pa
.Platform
.Modules
[F
].M
.Module
.Packages
:
389 if (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, DecType
) in Package
.Pcds
:
390 if DecDefaultValue
== None:
391 DecDefaultValue
= Package
.Pcds
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, DecType
].DefaultValue
393 DscDefaultValue
= None
394 if (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
) in self
.BuildDatabase
.WorkspaceDb
.PlatformList
[0].Pcds
:
395 DscDefaultValue
= self
.BuildDatabase
.WorkspaceDb
.PlatformList
[0].Pcds
[(Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
)].DefaultValue
397 DscModuleOverrideDefaultValue
= None
398 if F
in self
.BuildDatabase
.WorkspaceDb
.PlatformList
[0].Modules
:
399 if (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
) in self
.BuildDatabase
.WorkspaceDb
.PlatformList
[0].Modules
[F
].Pcds
:
400 DscModuleOverrideDefaultValue
= self
.BuildDatabase
.WorkspaceDb
.PlatformList
[0].Modules
[F
].Pcds
[(Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
)].DefaultValue
402 if Pcd
.DatumType
in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
403 if ModulePcd
.DefaultValue
.strip()[0:2].upper() == '0X':
404 ModulePcdDefaultValueNumber
= int(ModulePcd
.DefaultValue
.strip(), 16)
406 ModulePcdDefaultValueNumber
= int(ModulePcd
.DefaultValue
.strip())
408 if DecDefaultValue
== None:
411 if DecDefaultValue
.strip()[0:2].upper() == '0X':
412 DecDefaultValueNumber
= int(DecDefaultValue
.strip(), 16)
414 DecDefaultValueNumber
= int(DecDefaultValue
.strip())
415 DecMatch
= (DecDefaultValueNumber
== ModulePcdDefaultValueNumber
)
417 if InfDefaultValue
== None:
420 if InfDefaultValue
.strip()[0:2].upper() == '0X':
421 InfDefaultValueNumber
= int(InfDefaultValue
.strip(), 16)
423 InfDefaultValueNumber
= int(InfDefaultValue
.strip())
424 InfMatch
= (InfDefaultValueNumber
== ModulePcdDefaultValueNumber
)
426 if DscDefaultValue
== None:
429 if DscDefaultValue
.strip()[0:2].upper() == '0X':
430 DscDefaultValueNumber
= int(DscDefaultValue
.strip(), 16)
432 DscDefaultValueNumber
= int(DscDefaultValue
.strip())
433 DscMatch
= (DscDefaultValueNumber
== ModulePcdDefaultValueNumber
)
435 if DecDefaultValue
== None:
438 DecMatch
= (DecDefaultValue
== ModulePcd
.DefaultValue
)
440 if InfDefaultValue
== None:
443 InfMatch
= (InfDefaultValue
== ModulePcd
.DefaultValue
)
445 if DscDefaultValue
== None:
448 DscMatch
= (DscDefaultValue
== ModulePcd
.DefaultValue
)
450 if DecMatch
and InfMatch
:
451 Fd
.write (' %-*s: %6s %10s = %-22s\n' % (MaxLen
, Pcd
.TokenCName
, TypeName
, '('+Pcd
.DatumType
+')', ModulePcd
.DefaultValue
))
453 if DscMatch
and DscModuleOverrideDefaultValue
== None:
454 if (Pcd
.TokenCName
, Key
) in PcdSet
:
455 Fd
.write (' *F %-*s: %6s %10s = %-22s\n' % (MaxLen
, Pcd
.TokenCName
, TypeName
, '('+Pcd
.DatumType
+')', ModulePcd
.DefaultValue
))
457 Fd
.write (' *P %-*s: %6s %10s = %-22s\n' % (MaxLen
, Pcd
.TokenCName
, TypeName
, '('+Pcd
.DatumType
+')', ModulePcd
.DefaultValue
))
459 Fd
.write (' *M %-*s: %6s %10s = %-22s\n' % (MaxLen
, Pcd
.TokenCName
, TypeName
, '('+Pcd
.DatumType
+')', ModulePcd
.DefaultValue
))
460 if DscDefaultValue
<> None:
461 Fd
.write (' %*s = %s\n' % (MaxLen
+ 19, 'DSC DEFAULT', DscDefaultValue
))
462 if InfDefaultValue
<> None:
463 Fd
.write (' %*s = %s\n' % (MaxLen
+ 19, 'INF DEFAULT', InfDefaultValue
))
464 if DecDefaultValue
<> None and not DecMatch
:
465 Fd
.write (' %*s = %s\n' % (MaxLen
+ 19, 'DEC DEFAULT', DecDefaultValue
))
466 Fd
.write ('-------------------------------------------------------------------------------\n')
467 Fd
.write ('LIBRARIES\n')
468 Fd
.write ('-------------------------------------------------------------------------------\n')
469 for Lib
in Pa
.Platform
.Modules
[F
].M
.DependentLibraryList
:
470 if len(Lib
.ConstructorList
) > 0:
471 if len(Lib
.DestructorList
) > 0:
476 if len(Lib
.DestructorList
) > 0:
480 Fd
.write (' %s\n' % (Lib
))
481 for Depex
in Lib
.DepexExpression
[Pa
.Platform
.Modules
[F
].M
.Arch
, Pa
.Platform
.Modules
[F
].M
.ModuleType
]:
482 Fd
.write (' DEPEX = %s\n' % (Depex
))
483 Fd
.write ('-------------------------------------------------------------------------------\n')
485 Fd
.write ('MODULE DEPENDENCY EXPRESSION\n')
486 if len(Pa
.Platform
.Modules
[F
].M
.Module
.DepexExpression
[Pa
.Platform
.Modules
[F
].M
.Arch
, Pa
.Platform
.Modules
[F
].M
.ModuleType
]) == 0:
489 for Depex
in Pa
.Platform
.Modules
[F
].M
.Module
.DepexExpression
[Pa
.Platform
.Modules
[F
].M
.Arch
, Pa
.Platform
.Modules
[F
].M
.ModuleType
]:
490 Fd
.write (' %s\n' % (Depex
))
491 Fd
.write ('-------------------------------------------------------------------------------\n')
493 Fd
.write ('MODULE + LIBRARY DEPENDENCY EXPRESSION\n')
494 if Pa
.Platform
.Modules
[F
].M
.ModuleType
in Pa
.Platform
.Modules
[F
].M
.DepexExpressionList
:
495 if Pa
.Platform
.Modules
[F
].M
.DepexExpressionList
[Pa
.Platform
.Modules
[F
].M
.ModuleType
] == '':
498 Fd
.write (' %s\n' % (Pa
.Platform
.Modules
[F
].M
.DepexExpressionList
[Pa
.Platform
.Modules
[F
].M
.ModuleType
]))
501 Fd
.write ('-------------------------------------------------------------------------------\n')
505 EdkLogger
.error(None, FILE_OPEN_FAILURE
, ExtraData
=self
.ReportFile
)
507 self
._BuildDir
= None
509 self
._MakeFileDir
= None
510 self
._BuildCommand
= None
515 return "%s [%s]" % (self
.MetaFile
, ", ".join(self
.ArchList
))
517 ## Return the directory to store FV files
519 if self
._FvDir
== None:
520 self
._FvDir
= path
.join(self
.BuildDir
, 'FV')
523 ## Return the directory to store all intermediate and final files built
524 def _GetBuildDir(self
):
525 return self
.AutoGenObjectList
[0].BuildDir
527 ## Return the build output directory platform specifies
528 def _GetOutputDir(self
):
529 return self
.Platform
.OutputDirectory
531 ## Return platform name
533 return self
.Platform
.PlatformName
535 ## Return meta-file GUID
537 return self
.Platform
.Guid
539 ## Return platform version
540 def _GetVersion(self
):
541 return self
.Platform
.Version
543 ## Return paths of tools
544 def _GetToolDefinition(self
):
545 return self
.AutoGenObjectList
[0].ToolDefinition
547 ## Return directory of platform makefile
549 # @retval string Makefile directory
551 def _GetMakeFileDir(self
):
552 if self
._MakeFileDir
== None:
553 self
._MakeFileDir
= self
.BuildDir
554 return self
._MakeFileDir
556 ## Return build command string
558 # @retval string Build command string
560 def _GetBuildCommand(self
):
561 if self
._BuildCommand
== None:
562 # BuildCommand should be all the same. So just get one from platform AutoGen
563 self
._BuildCommand
= self
.AutoGenObjectList
[0].BuildCommand
564 return self
._BuildCommand
566 ## Create makefile for the platform and mdoules in it
568 # @param CreateDepsMakeFile Flag indicating if the makefile for
569 # modules will be created as well
571 def CreateMakeFile(self
, CreateDepsMakeFile
=False):
572 # create makefile for platform
573 Makefile
= GenMake
.TopLevelMakefile(self
)
574 if Makefile
.Generate():
575 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for platform [%s] %s\n" %
576 (self
.MetaFile
, self
.ArchList
))
578 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for platform [%s] %s\n" %
579 (self
.MetaFile
, self
.ArchList
))
581 if CreateDepsMakeFile
:
582 for Pa
in self
.AutoGenObjectList
:
583 Pa
.CreateMakeFile(CreateDepsMakeFile
)
585 ## Create autogen code for platform and modules
587 # Since there's no autogen code for platform, this method will do nothing
588 # if CreateModuleCodeFile is set to False.
590 # @param CreateDepsCodeFile Flag indicating if creating module's
591 # autogen code file or not
593 def CreateCodeFile(self
, CreateDepsCodeFile
=False):
594 if not CreateDepsCodeFile
:
596 for Pa
in self
.AutoGenObjectList
:
597 Pa
.CreateCodeFile(CreateDepsCodeFile
)
599 Name
= property(_GetName
)
600 Guid
= property(_GetGuid
)
601 Version
= property(_GetVersion
)
602 OutputDir
= property(_GetOutputDir
)
604 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
606 BuildDir
= property(_GetBuildDir
)
607 FvDir
= property(_GetFvDir
)
608 MakeFileDir
= property(_GetMakeFileDir
)
609 BuildCommand
= property(_GetBuildCommand
)
611 ## AutoGen class for platform
613 # PlatformAutoGen class will process the original information in platform
614 # file in order to generate makefile for platform.
616 class PlatformAutoGen(AutoGen
):
618 # Used to store all PCDs for both PEI and DXE phase, in order to generate
619 # correct PCD database
622 _NonDynaPcdList_
= []
624 ## The real constructor of PlatformAutoGen
626 # This method is not supposed to be called by users of PlatformAutoGen. It's
627 # only used by factory method __new__() to do real initialization work for an
628 # object of PlatformAutoGen
630 # @param Workspace WorkspaceAutoGen object
631 # @param PlatformFile Platform file (DSC file)
632 # @param Target Build target (DEBUG, RELEASE)
633 # @param Toolchain Name of tool chain
634 # @param Arch arch of the platform supports
636 def _Init(self
, Workspace
, PlatformFile
, Target
, Toolchain
, Arch
):
637 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen platform [%s] [%s]" % (PlatformFile
, Arch
))
638 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (PlatformFile
, Arch
, Toolchain
, Target
)
640 self
.MetaFile
= PlatformFile
641 self
.Workspace
= Workspace
642 self
.WorkspaceDir
= Workspace
.WorkspaceDir
643 self
.ToolChain
= Toolchain
644 self
.BuildTarget
= Target
646 self
.SourceDir
= PlatformFile
.SubDir
647 self
.SourceOverrideDir
= None
648 self
.FdTargetList
= self
.Workspace
.FdTargetList
649 self
.FvTargetList
= self
.Workspace
.FvTargetList
651 # flag indicating if the makefile/C-code file has been created or not
652 self
.IsMakeFileCreated
= False
653 self
.IsCodeFileCreated
= False
655 self
._Platform
= None
660 self
._BuildRule
= None
661 self
._SourceDir
= None
662 self
._BuildDir
= None
663 self
._OutputDir
= None
665 self
._MakeFileDir
= None
668 self
._PcdTokenNumber
= None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
669 self
._DynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
670 self
._NonDynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
672 self
._ToolDefinitions
= None
673 self
._ToolDefFile
= None # toolcode : tool path
674 self
._ToolChainFamily
= None
675 self
._BuildRuleFamily
= None
676 self
._BuildOption
= None # toolcode : option
677 self
._PackageList
= None
678 self
._ModuleAutoGenList
= None
679 self
._LibraryAutoGenList
= None
680 self
._BuildCommand
= None
682 # get the original module/package/platform objects
683 self
.BuildDatabase
= Workspace
.BuildDatabase
687 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
689 ## Create autogen code for platform and modules
691 # Since there's no autogen code for platform, this method will do nothing
692 # if CreateModuleCodeFile is set to False.
694 # @param CreateModuleCodeFile Flag indicating if creating module's
695 # autogen code file or not
697 def CreateCodeFile(self
, CreateModuleCodeFile
=False):
698 # only module has code to be greated, so do nothing if CreateModuleCodeFile is False
699 if self
.IsCodeFileCreated
or not CreateModuleCodeFile
:
702 for Ma
in self
.ModuleAutoGenList
:
703 Ma
.CreateCodeFile(True)
705 # don't do this twice
706 self
.IsCodeFileCreated
= True
708 ## Create makefile for the platform and mdoules in it
710 # @param CreateModuleMakeFile Flag indicating if the makefile for
711 # modules will be created as well
713 def CreateMakeFile(self
, CreateModuleMakeFile
=False):
714 if CreateModuleMakeFile
:
715 for ModuleFile
in self
.Platform
.Modules
:
716 Ma
= ModuleAutoGen(self
.Workspace
, ModuleFile
, self
.BuildTarget
,
717 self
.ToolChain
, self
.Arch
, self
.MetaFile
)
718 Ma
.CreateMakeFile(True)
720 # no need to create makefile for the platform more than once
721 if self
.IsMakeFileCreated
:
724 # create makefile for platform
725 Makefile
= GenMake
.PlatformMakefile(self
)
726 if Makefile
.Generate():
727 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for platform [%s] [%s]\n" %
728 (self
.MetaFile
, self
.Arch
))
730 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for platform [%s] [%s]\n" %
731 (self
.MetaFile
, self
.Arch
))
732 self
.IsMakeFileCreated
= True
734 ## Collect dynamic PCDs
736 # Gather dynamic PCDs list from each module and their settings from platform
737 # This interface should be invoked explicitly when platform action is created.
739 def CollectPlatformDynamicPcds(self
):
740 # for gathering error information
741 NoDatumTypePcdList
= set()
744 for F
in self
.Platform
.Modules
.keys():
745 M
= ModuleAutoGen(self
.Workspace
, F
, self
.BuildTarget
, self
.ToolChain
, self
.Arch
, self
.MetaFile
)
746 #GuidValue.update(M.Guids)
748 self
.Platform
.Modules
[F
].M
= M
750 for PcdFromModule
in M
.ModulePcdList
+M
.LibraryPcdList
:
751 # make sure that the "VOID*" kind of datum has MaxDatumSize set
752 if PcdFromModule
.DatumType
== "VOID*" and PcdFromModule
.MaxDatumSize
== None:
753 NoDatumTypePcdList
.add("%s.%s [%s]" % (PcdFromModule
.TokenSpaceGuidCName
, PcdFromModule
.TokenCName
, F
))
755 if PcdFromModule
.Type
in GenC
.gDynamicPcd
or PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
757 # If a dynamic PCD used by a PEM module/PEI module & DXE module,
758 # it should be stored in Pcd PEI database, If a dynamic only
759 # used by DXE module, it should be stored in DXE PCD database.
760 # The default Phase is DXE
762 if M
.ModuleType
in ["PEIM", "PEI_CORE"]:
763 PcdFromModule
.Phase
= "PEI"
764 if PcdFromModule
not in self
._DynaPcdList
_:
765 self
._DynaPcdList
_.append(PcdFromModule
)
766 elif PcdFromModule
.Phase
== 'PEI':
767 # overwrite any the same PCD existing, if Phase is PEI
768 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
769 self
._DynaPcdList
_[Index
] = PcdFromModule
770 elif PcdFromModule
not in self
._NonDynaPcdList
_:
771 self
._NonDynaPcdList
_.append(PcdFromModule
)
773 # print out error information and break the build, if error found
774 if len(NoDatumTypePcdList
) > 0:
775 NoDatumTypePcdListString
= "\n\t\t".join(NoDatumTypePcdList
)
776 EdkLogger
.error("build", AUTOGEN_ERROR
, "PCD setting error",
778 ExtraData
="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
779 % NoDatumTypePcdListString
)
780 self
._NonDynamicPcdList
= self
._NonDynaPcdList
_
781 self
._DynamicPcdList
= self
._DynaPcdList
_
784 # Sort dynamic PCD list to:
785 # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should
786 # try to be put header of dynamicd List
787 # 2) If PCD is HII type, the PCD item should be put after unicode type PCD
789 # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.
794 for Pcd
in self
._DynamicPcdList
:
795 # just pick the a value to determine whether is unicode string type
796 Sku
= Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]]
797 PcdValue
= Sku
.DefaultValue
798 if Pcd
.DatumType
== 'VOID*' and PcdValue
.startswith("L"):
799 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
800 UnicodePcdArray
.append(Pcd
)
801 elif len(Sku
.VariableName
) > 0:
802 # if found HII type PCD then insert to right of UnicodeIndex
803 HiiPcdArray
.append(Pcd
)
805 OtherPcdArray
.append(Pcd
)
806 del self
._DynamicPcdList
[:]
807 self
._DynamicPcdList
.extend(UnicodePcdArray
)
808 self
._DynamicPcdList
.extend(HiiPcdArray
)
809 self
._DynamicPcdList
.extend(OtherPcdArray
)
812 ## Return the platform build data object
813 def _GetPlatform(self
):
814 if self
._Platform
== None:
815 self
._Platform
= self
.BuildDatabase
[self
.MetaFile
, self
.Arch
]
816 return self
._Platform
818 ## Return platform name
820 return self
.Platform
.PlatformName
822 ## Return the meta file GUID
824 return self
.Platform
.Guid
826 ## Return the platform version
827 def _GetVersion(self
):
828 return self
.Platform
.Version
830 ## Return the FDF file name
831 def _GetFdfFile(self
):
832 if self
._FdfFile
== None:
833 if self
.Workspace
.FdfFile
!= "":
834 self
._FdfFile
= path
.join(self
.WorkspaceDir
, self
.Workspace
.FdfFile
)
839 ## Return the build output directory platform specifies
840 def _GetOutputDir(self
):
841 return self
.Platform
.OutputDirectory
843 ## Return the directory to store all intermediate and final files built
844 def _GetBuildDir(self
):
845 if self
._BuildDir
== None:
846 if os
.path
.isabs(self
.OutputDir
):
847 self
._BuildDir
= path
.join(
848 path
.abspath(self
.OutputDir
),
849 self
.BuildTarget
+ "_" + self
.ToolChain
,
852 self
._BuildDir
= path
.join(
855 self
.BuildTarget
+ "_" + self
.ToolChain
,
857 return self
._BuildDir
859 ## Return directory of platform makefile
861 # @retval string Makefile directory
863 def _GetMakeFileDir(self
):
864 if self
._MakeFileDir
== None:
865 self
._MakeFileDir
= path
.join(self
.BuildDir
, self
.Arch
)
866 return self
._MakeFileDir
868 ## Return build command string
870 # @retval string Build command string
872 def _GetBuildCommand(self
):
873 if self
._BuildCommand
== None:
874 self
._BuildCommand
= []
875 if "MAKE" in self
.ToolDefinition
and "PATH" in self
.ToolDefinition
["MAKE"]:
876 self
._BuildCommand
+= SplitOption(self
.ToolDefinition
["MAKE"]["PATH"])
877 if "FLAGS" in self
.ToolDefinition
["MAKE"]:
878 NewOption
= self
.ToolDefinition
["MAKE"]["FLAGS"].strip()
880 self
._BuildCommand
+= SplitOption(NewOption
)
881 return self
._BuildCommand
883 ## Get tool chain definition
885 # Get each tool defition for given tool chain from tools_def.txt and platform
887 def _GetToolDefinition(self
):
888 if self
._ToolDefinitions
== None:
889 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDictionary
890 if TAB_TOD_DEFINES_COMMAND_TYPE
not in self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
:
891 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No tools found in configuration",
892 ExtraData
="[%s]" % self
.MetaFile
)
893 self
._ToolDefinitions
= {}
895 for Def
in ToolDefinition
:
896 Target
, Tag
, Arch
, Tool
, Attr
= Def
.split("_")
897 if Target
!= self
.BuildTarget
or Tag
!= self
.ToolChain
or Arch
!= self
.Arch
:
900 Value
= ToolDefinition
[Def
]
901 # don't record the DLL
903 DllPathList
.add(Value
)
906 if Tool
not in self
._ToolDefinitions
:
907 self
._ToolDefinitions
[Tool
] = {}
908 self
._ToolDefinitions
[Tool
][Attr
] = Value
912 if GlobalData
.gOptions
.SilentMode
and "MAKE" in self
._ToolDefinitions
:
913 if "FLAGS" not in self
._ToolDefinitions
["MAKE"]:
914 self
._ToolDefinitions
["MAKE"]["FLAGS"] = ""
915 self
._ToolDefinitions
["MAKE"]["FLAGS"] += " -s"
917 for Tool
in self
._ToolDefinitions
:
918 for Attr
in self
._ToolDefinitions
[Tool
]:
919 Value
= self
._ToolDefinitions
[Tool
][Attr
]
920 if Tool
in self
.BuildOption
and Attr
in self
.BuildOption
[Tool
]:
921 # check if override is indicated
922 if self
.BuildOption
[Tool
][Attr
].startswith('='):
923 Value
= self
.BuildOption
[Tool
][Attr
][1:]
925 Value
+= " " + self
.BuildOption
[Tool
][Attr
]
928 # Don't put MAKE definition in the file
932 ToolsDef
+= "%s = %s\n" % (Tool
, Value
)
934 # Don't put MAKE definition in the file
939 ToolsDef
+= "%s_%s = %s\n" % (Tool
, Attr
, Value
)
942 SaveFileOnChange(self
.ToolDefinitionFile
, ToolsDef
)
943 for DllPath
in DllPathList
:
944 os
.environ
["PATH"] = DllPath
+ os
.pathsep
+ os
.environ
["PATH"]
945 os
.environ
["MAKE_FLAGS"] = MakeFlags
947 return self
._ToolDefinitions
949 ## Return the paths of tools
950 def _GetToolDefFile(self
):
951 if self
._ToolDefFile
== None:
952 self
._ToolDefFile
= os
.path
.join(self
.MakeFileDir
, "TOOLS_DEF." + self
.Arch
)
953 return self
._ToolDefFile
955 ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.
956 def _GetToolChainFamily(self
):
957 if self
._ToolChainFamily
== None:
958 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
959 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
960 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
961 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]:
962 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
964 self
._ToolChainFamily
= "MSFT"
966 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]
967 return self
._ToolChainFamily
969 def _GetBuildRuleFamily(self
):
970 if self
._BuildRuleFamily
== None:
971 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
972 if TAB_TOD_DEFINES_BUILDRULEFAMILY
not in ToolDefinition \
973 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
] \
974 or not ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]:
975 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
977 self
._BuildRuleFamily
= "MSFT"
979 self
._BuildRuleFamily
= ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]
980 return self
._BuildRuleFamily
982 ## Return the build options specific to this platform
983 def _GetBuildOptions(self
):
984 if self
._BuildOption
== None:
985 self
._BuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
)
986 return self
._BuildOption
988 ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt
990 # @retval BuildRule object
992 def _GetBuildRule(self
):
993 if self
._BuildRule
== None:
995 if TAB_TAT_DEFINES_BUILD_RULE_CONF
in self
.Workspace
.TargetTxt
.TargetTxtDictionary
:
996 BuildRuleFile
= self
.Workspace
.TargetTxt
.TargetTxtDictionary
[TAB_TAT_DEFINES_BUILD_RULE_CONF
]
997 if BuildRuleFile
in [None, '']:
998 BuildRuleFile
= gBuildRuleFile
999 self
._BuildRule
= BuildRule(BuildRuleFile
)
1000 return self
._BuildRule
1002 ## Summarize the packages used by modules in this platform
1003 def _GetPackageList(self
):
1004 if self
._PackageList
== None:
1005 self
._PackageList
= set()
1006 for La
in self
.LibraryAutoGenList
:
1007 self
._PackageList
.update(La
.DependentPackageList
)
1008 for Ma
in self
.ModuleAutoGenList
:
1009 self
._PackageList
.update(Ma
.DependentPackageList
)
1010 self
._PackageList
= list(self
._PackageList
)
1011 return self
._PackageList
1013 ## Get list of non-dynamic PCDs
1014 def _GetNonDynamicPcdList(self
):
1015 return self
._NonDynamicPcdList
1017 ## Get list of dynamic PCDs
1018 def _GetDynamicPcdList(self
):
1019 return self
._DynamicPcdList
1021 ## Generate Token Number for all PCD
1022 def _GetPcdTokenNumbers(self
):
1023 if self
._PcdTokenNumber
== None:
1024 self
._PcdTokenNumber
= sdict()
1026 for Pcd
in self
.DynamicPcdList
:
1027 if Pcd
.Phase
== "PEI":
1028 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
1029 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1032 for Pcd
in self
.DynamicPcdList
:
1033 if Pcd
.Phase
== "DXE":
1034 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
1035 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1038 for Pcd
in self
.NonDynamicPcdList
:
1039 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1041 return self
._PcdTokenNumber
1043 ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform
1044 def _GetAutoGenObjectList(self
):
1045 self
._ModuleAutoGenList
= []
1046 self
._LibraryAutoGenList
= []
1047 for ModuleFile
in self
.Platform
.Modules
:
1056 if Ma
not in self
._ModuleAutoGenList
:
1057 self
._ModuleAutoGenList
.append(Ma
)
1058 for La
in Ma
.LibraryAutoGenList
:
1059 if La
not in self
._LibraryAutoGenList
:
1060 self
._LibraryAutoGenList
.append(La
)
1062 ## Summarize ModuleAutoGen objects of all modules to be built for this platform
1063 def _GetModuleAutoGenList(self
):
1064 if self
._ModuleAutoGenList
== None:
1065 self
._GetAutoGenObjectList
()
1066 return self
._ModuleAutoGenList
1068 ## Summarize ModuleAutoGen objects of all libraries to be built for this platform
1069 def _GetLibraryAutoGenList(self
):
1070 if self
._LibraryAutoGenList
== None:
1071 self
._GetAutoGenObjectList
()
1072 return self
._LibraryAutoGenList
1074 ## Test if a module is supported by the platform
1076 # An error will be raised directly if the module or its arch is not supported
1077 # by the platform or current configuration
1079 def ValidModule(self
, Module
):
1080 return Module
in self
.Platform
.Modules
or Module
in self
.Platform
.LibraryInstances
1082 ## Resolve the library classes in a module to library instances
1084 # This method will not only resolve library classes but also sort the library
1085 # instances according to the dependency-ship.
1087 # @param Module The module from which the library classes will be resolved
1089 # @retval library_list List of library instances sorted
1091 def ApplyLibraryInstance(self
, Module
):
1092 ModuleType
= Module
.ModuleType
1094 # for overridding library instances with module specific setting
1095 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1097 # add forced library instances (specified under LibraryClasses sections)
1098 for LibraryClass
in self
.Platform
.LibraryClasses
.GetKeys():
1099 if LibraryClass
.startswith("NULL"):
1100 Module
.LibraryClasses
[LibraryClass
] = self
.Platform
.LibraryClasses
[LibraryClass
]
1102 # add forced library instances (specified in module overrides)
1103 for LibraryClass
in PlatformModule
.LibraryClasses
:
1104 if LibraryClass
.startswith("NULL"):
1105 Module
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
1108 LibraryConsumerList
= [Module
]
1110 ConsumedByList
= sdict()
1111 LibraryInstance
= sdict()
1113 EdkLogger
.verbose("")
1114 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
1115 while len(LibraryConsumerList
) > 0:
1116 M
= LibraryConsumerList
.pop()
1117 for LibraryClassName
in M
.LibraryClasses
:
1118 if LibraryClassName
not in LibraryInstance
:
1119 # override library instance for this module
1120 if LibraryClassName
in PlatformModule
.LibraryClasses
:
1121 LibraryPath
= PlatformModule
.LibraryClasses
[LibraryClassName
]
1123 LibraryPath
= self
.Platform
.LibraryClasses
[LibraryClassName
, ModuleType
]
1124 if LibraryPath
== None or LibraryPath
== "":
1125 LibraryPath
= M
.LibraryClasses
[LibraryClassName
]
1126 if LibraryPath
== None or LibraryPath
== "":
1127 EdkLogger
.error("build", RESOURCE_NOT_AVAILABLE
,
1128 "Instance of library class [%s] is not found" % LibraryClassName
,
1130 ExtraData
="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M
), self
.Arch
, str(Module
)))
1132 LibraryModule
= self
.BuildDatabase
[LibraryPath
, self
.Arch
]
1133 # for those forced library instance (NULL library), add a fake library class
1134 if LibraryClassName
.startswith("NULL"):
1135 LibraryModule
.LibraryClass
.append(LibraryClassObject(LibraryClassName
, [ModuleType
]))
1136 elif LibraryModule
.LibraryClass
== None \
1137 or len(LibraryModule
.LibraryClass
) == 0 \
1138 or (ModuleType
!= 'USER_DEFINED'
1139 and ModuleType
not in LibraryModule
.LibraryClass
[0].SupModList
):
1140 # only USER_DEFINED can link against any library instance despite of its SupModList
1141 EdkLogger
.error("build", OPTION_MISSING
,
1142 "Module type [%s] is not supported by library instance [%s]" \
1143 % (ModuleType
, LibraryPath
), File
=self
.MetaFile
,
1144 ExtraData
="consumed by [%s]" % str(Module
))
1146 LibraryInstance
[LibraryClassName
] = LibraryModule
1147 LibraryConsumerList
.append(LibraryModule
)
1148 EdkLogger
.verbose("\t" + str(LibraryClassName
) + " : " + str(LibraryModule
))
1150 LibraryModule
= LibraryInstance
[LibraryClassName
]
1152 if LibraryModule
== None:
1155 if LibraryModule
.ConstructorList
!= [] and LibraryModule
not in Constructor
:
1156 Constructor
.append(LibraryModule
)
1158 if LibraryModule
not in ConsumedByList
:
1159 ConsumedByList
[LibraryModule
] = []
1160 # don't add current module itself to consumer list
1162 if M
in ConsumedByList
[LibraryModule
]:
1164 ConsumedByList
[LibraryModule
].append(M
)
1166 # Initialize the sorted output list to the empty set
1168 SortedLibraryList
= []
1170 # Q <- Set of all nodes with no incoming edges
1172 LibraryList
= [] #LibraryInstance.values()
1174 for LibraryClassName
in LibraryInstance
:
1175 M
= LibraryInstance
[LibraryClassName
]
1176 LibraryList
.append(M
)
1177 if ConsumedByList
[M
] == []:
1181 # start the DAG algorithm
1185 while Q
== [] and EdgeRemoved
:
1187 # for each node Item with a Constructor
1188 for Item
in LibraryList
:
1189 if Item
not in Constructor
:
1191 # for each Node without a constructor with an edge e from Item to Node
1192 for Node
in ConsumedByList
[Item
]:
1193 if Node
in Constructor
:
1195 # remove edge e from the graph if Node has no constructor
1196 ConsumedByList
[Item
].remove(Node
)
1198 if ConsumedByList
[Item
] == []:
1199 # insert Item into Q
1204 # DAG is done if there's no more incoming edge for all nodes
1208 # remove node from Q
1211 SortedLibraryList
.append(Node
)
1213 # for each node Item with an edge e from Node to Item do
1214 for Item
in LibraryList
:
1215 if Node
not in ConsumedByList
[Item
]:
1217 # remove edge e from the graph
1218 ConsumedByList
[Item
].remove(Node
)
1220 if ConsumedByList
[Item
] != []:
1222 # insert Item into Q, if Item has no other incoming edges
1226 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
1228 for Item
in LibraryList
:
1229 if ConsumedByList
[Item
] != [] and Item
in Constructor
and len(Constructor
) > 1:
1230 ErrorMessage
= "\tconsumed by " + "\n\tconsumed by ".join([str(L
) for L
in ConsumedByList
[Item
]])
1231 EdkLogger
.error("build", BUILD_ERROR
, 'Library [%s] with constructors has a cycle' % str(Item
),
1232 ExtraData
=ErrorMessage
, File
=self
.MetaFile
)
1233 if Item
not in SortedLibraryList
:
1234 SortedLibraryList
.append(Item
)
1237 # Build the list of constructor and destructir names
1238 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
1240 SortedLibraryList
.reverse()
1241 return SortedLibraryList
1244 ## Override PCD setting (type, value, ...)
1246 # @param ToPcd The PCD to be overrided
1247 # @param FromPcd The PCD overrideing from
1249 def _OverridePcd(self
, ToPcd
, FromPcd
, Module
=""):
1251 # in case there's PCDs coming from FDF file, which have no type given.
1252 # at this point, ToPcd.Type has the type found from dependent
1256 if ToPcd
.Pending
and FromPcd
.Type
not in [None, '']:
1257 ToPcd
.Type
= FromPcd
.Type
1258 elif ToPcd
.Type
not in [None, ''] and FromPcd
.Type
not in [None, ''] \
1259 and ToPcd
.Type
!= FromPcd
.Type
:
1260 EdkLogger
.error("build", OPTION_CONFLICT
, "Mismatched PCD type",
1261 ExtraData
="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
1262 % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
,
1263 ToPcd
.Type
, Module
, FromPcd
.Type
),
1266 if FromPcd
.MaxDatumSize
not in [None, '']:
1267 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
1268 if FromPcd
.DefaultValue
not in [None, '']:
1269 ToPcd
.DefaultValue
= FromPcd
.DefaultValue
1270 if FromPcd
.TokenValue
not in [None, '']:
1271 ToPcd
.TokenValue
= FromPcd
.TokenValue
1272 if FromPcd
.MaxDatumSize
not in [None, '']:
1273 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
1274 if FromPcd
.DatumType
not in [None, '']:
1275 ToPcd
.DatumType
= FromPcd
.DatumType
1276 if FromPcd
.SkuInfoList
not in [None, '', []]:
1277 ToPcd
.SkuInfoList
= FromPcd
.SkuInfoList
1279 # check the validation of datum
1280 IsValid
, Cause
= CheckPcdDatum(ToPcd
.DatumType
, ToPcd
.DefaultValue
)
1282 EdkLogger
.error('build', FORMAT_INVALID
, Cause
, File
=self
.MetaFile
,
1283 ExtraData
="%s.%s" % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
))
1285 if ToPcd
.DatumType
== "VOID*" and ToPcd
.MaxDatumSize
in ['', None]:
1286 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "No MaxDatumSize specified for PCD %s.%s" \
1287 % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
))
1288 Value
= ToPcd
.DefaultValue
1289 if Value
in [None, '']:
1290 ToPcd
.MaxDatumSize
= 1
1291 elif Value
[0] == 'L':
1292 ToPcd
.MaxDatumSize
= str(len(Value
) * 2)
1293 elif Value
[0] == '{':
1294 ToPcd
.MaxDatumSize
= str(len(Value
.split(',')))
1296 ToPcd
.MaxDatumSize
= str(len(Value
))
1298 # apply default SKU for dynamic PCDS if specified one is not available
1299 if (ToPcd
.Type
in PCD_DYNAMIC_TYPE_LIST
or ToPcd
.Type
in PCD_DYNAMIC_EX_TYPE_LIST
) \
1300 and ToPcd
.SkuInfoList
in [None, {}, '']:
1301 if self
.Platform
.SkuName
in self
.Platform
.SkuIds
:
1302 SkuName
= self
.Platform
.SkuName
1305 ToPcd
.SkuInfoList
= {
1306 SkuName
: SkuInfoClass(SkuName
, self
.Platform
.SkuIds
[SkuName
], '', '', '', '', '', ToPcd
.DefaultValue
)
1309 ## Apply PCD setting defined platform to a module
1311 # @param Module The module from which the PCD setting will be overrided
1313 # @retval PCD_list The list PCDs with settings from platform
1315 def ApplyPcdSetting(self
, Module
, Pcds
):
1316 # for each PCD in module
1317 for Name
,Guid
in Pcds
:
1318 PcdInModule
= Pcds
[Name
,Guid
]
1319 # find out the PCD setting in platform
1320 if (Name
,Guid
) in self
.Platform
.Pcds
:
1321 PcdInPlatform
= self
.Platform
.Pcds
[Name
,Guid
]
1323 PcdInPlatform
= None
1324 # then override the settings if any
1325 self
._OverridePcd
(PcdInModule
, PcdInPlatform
, Module
)
1326 # resolve the VariableGuid value
1327 for SkuId
in PcdInModule
.SkuInfoList
:
1328 Sku
= PcdInModule
.SkuInfoList
[SkuId
]
1329 if Sku
.VariableGuid
== '': continue
1330 Sku
.VariableGuidValue
= GuidValue(Sku
.VariableGuid
, self
.PackageList
)
1331 if Sku
.VariableGuidValue
== None:
1332 PackageList
= "\n\t".join([str(P
) for P
in self
.PackageList
])
1335 RESOURCE_NOT_AVAILABLE
,
1336 "Value of GUID [%s] is not found in" % Sku
.VariableGuid
,
1337 ExtraData
=PackageList
+ "\n\t(used with %s.%s from module %s)" \
1338 % (Guid
, Name
, str(Module
)),
1342 # override PCD settings with module specific setting
1343 if Module
in self
.Platform
.Modules
:
1344 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1345 for Key
in PlatformModule
.Pcds
:
1347 self
._OverridePcd
(Pcds
[Key
], PlatformModule
.Pcds
[Key
], Module
)
1348 return Pcds
.values()
1350 ## Resolve library names to library modules
1352 # (for R8.x modules)
1354 # @param Module The module from which the library names will be resolved
1356 # @retval library_list The list of library modules
1358 def ResolveLibraryReference(self
, Module
):
1359 EdkLogger
.verbose("")
1360 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
1361 LibraryConsumerList
= [Module
]
1363 # "CompilerStub" is a must for R8 modules
1364 if Module
.Libraries
:
1365 Module
.Libraries
.append("CompilerStub")
1367 while len(LibraryConsumerList
) > 0:
1368 M
= LibraryConsumerList
.pop()
1369 for LibraryName
in M
.Libraries
:
1370 Library
= self
.Platform
.LibraryClasses
[LibraryName
, ':dummy:']
1372 for Key
in self
.Platform
.LibraryClasses
.data
.keys():
1373 if LibraryName
.upper() == Key
.upper():
1374 Library
= self
.Platform
.LibraryClasses
[Key
, ':dummy:']
1377 EdkLogger
.warn("build", "Library [%s] is not found" % LibraryName
, File
=str(M
),
1378 ExtraData
="\t%s [%s]" % (str(Module
), self
.Arch
))
1381 if Library
not in LibraryList
:
1382 LibraryList
.append(Library
)
1383 LibraryConsumerList
.append(Library
)
1384 EdkLogger
.verbose("\t" + LibraryName
+ " : " + str(Library
) + ' ' + str(type(Library
)))
1387 ## Expand * in build option key
1389 # @param Options Options to be expanded
1391 # @retval options Options expanded
1393 def _ExpandBuildOption(self
, Options
):
1399 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
1400 # if tool chain family doesn't match, skip it
1401 if Tool
in self
.ToolDefinition
and Family
!= "":
1402 FamilyIsNull
= False
1403 if self
.ToolDefinition
[Tool
].get(TAB_TOD_DEFINES_BUILDRULEFAMILY
, "") != "":
1404 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_BUILDRULEFAMILY
]:
1406 elif Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
1409 # expand any wildcard
1410 if Target
== "*" or Target
== self
.BuildTarget
:
1411 if Tag
== "*" or Tag
== self
.ToolChain
:
1412 if Arch
== "*" or Arch
== self
.Arch
:
1413 if Tool
not in BuildOptions
:
1414 BuildOptions
[Tool
] = {}
1415 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
]:
1416 BuildOptions
[Tool
][Attr
] = Options
[Key
]
1418 # append options for the same tool
1419 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
1420 # Build Option Family has been checked, which need't to be checked again for family.
1421 if FamilyMatch
or FamilyIsNull
:
1426 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
1427 # if tool chain family doesn't match, skip it
1428 if Tool
not in self
.ToolDefinition
or Family
=="":
1430 # option has been added before
1431 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
1434 # expand any wildcard
1435 if Target
== "*" or Target
== self
.BuildTarget
:
1436 if Tag
== "*" or Tag
== self
.ToolChain
:
1437 if Arch
== "*" or Arch
== self
.Arch
:
1438 if Tool
not in BuildOptions
:
1439 BuildOptions
[Tool
] = {}
1440 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
]:
1441 BuildOptions
[Tool
][Attr
] = Options
[Key
]
1443 # append options for the same tool
1444 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
1447 ## Append build options in platform to a module
1449 # @param Module The module to which the build options will be appened
1451 # @retval options The options appended with build options in platform
1453 def ApplyBuildOption(self
, Module
):
1454 PlatformOptions
= self
.BuildOption
1455 ModuleOptions
= self
._ExpandBuildOption
(Module
.BuildOptions
)
1456 if Module
in self
.Platform
.Modules
:
1457 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1458 PlatformModuleOptions
= self
._ExpandBuildOption
(PlatformModule
.BuildOptions
)
1460 PlatformModuleOptions
= {}
1462 AllTools
= set(ModuleOptions
.keys() + PlatformOptions
.keys() + PlatformModuleOptions
.keys() + self
.ToolDefinition
.keys())
1464 for Tool
in AllTools
:
1465 if Tool
not in BuildOptions
:
1466 BuildOptions
[Tool
] = {}
1468 for Options
in [self
.ToolDefinition
, ModuleOptions
, PlatformOptions
, PlatformModuleOptions
]:
1469 if Tool
not in Options
:
1471 for Attr
in Options
[Tool
]:
1472 Value
= Options
[Tool
][Attr
]
1473 if Attr
not in BuildOptions
[Tool
]:
1474 BuildOptions
[Tool
][Attr
] = ""
1475 # check if override is indicated
1476 if Value
.startswith('='):
1477 BuildOptions
[Tool
][Attr
] = Value
[1:]
1479 BuildOptions
[Tool
][Attr
] += " " + Value
1482 Platform
= property(_GetPlatform
)
1483 Name
= property(_GetName
)
1484 Guid
= property(_GetGuid
)
1485 Version
= property(_GetVersion
)
1487 OutputDir
= property(_GetOutputDir
)
1488 BuildDir
= property(_GetBuildDir
)
1489 MakeFileDir
= property(_GetMakeFileDir
)
1490 FdfFile
= property(_GetFdfFile
)
1492 PcdTokenNumber
= property(_GetPcdTokenNumbers
) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
1493 DynamicPcdList
= property(_GetDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1494 NonDynamicPcdList
= property(_GetNonDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1495 PackageList
= property(_GetPackageList
)
1497 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
1498 ToolDefinitionFile
= property(_GetToolDefFile
) # toolcode : lib path
1499 ToolChainFamily
= property(_GetToolChainFamily
)
1500 BuildRuleFamily
= property(_GetBuildRuleFamily
)
1501 BuildOption
= property(_GetBuildOptions
) # toolcode : option
1503 BuildCommand
= property(_GetBuildCommand
)
1504 BuildRule
= property(_GetBuildRule
)
1505 ModuleAutoGenList
= property(_GetModuleAutoGenList
)
1506 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
1508 ## ModuleAutoGen class
1510 # This class encapsules the AutoGen behaviors for the build tools. In addition to
1511 # the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according
1512 # to the [depex] section in module's inf file.
1514 class ModuleAutoGen(AutoGen
):
1515 ## The real constructor of ModuleAutoGen
1517 # This method is not supposed to be called by users of ModuleAutoGen. It's
1518 # only used by factory method __new__() to do real initialization work for an
1519 # object of ModuleAutoGen
1521 # @param Workspace EdkIIWorkspaceBuild object
1522 # @param ModuleFile The path of module file
1523 # @param Target Build target (DEBUG, RELEASE)
1524 # @param Toolchain Name of tool chain
1525 # @param Arch The arch the module supports
1526 # @param PlatformFile Platform meta-file
1528 def _Init(self
, Workspace
, ModuleFile
, Target
, Toolchain
, Arch
, PlatformFile
):
1529 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen module [%s] [%s]" % (ModuleFile
, Arch
))
1530 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (ModuleFile
, Arch
, Toolchain
, Target
)
1532 self
.Workspace
= Workspace
1533 self
.WorkspaceDir
= Workspace
.WorkspaceDir
1535 self
.MetaFile
= ModuleFile
1536 self
.PlatformInfo
= PlatformAutoGen(Workspace
, PlatformFile
, Target
, Toolchain
, Arch
)
1537 # check if this module is employed by active platform
1538 if not self
.PlatformInfo
.ValidModule(self
.MetaFile
):
1539 EdkLogger
.verbose("Module [%s] for [%s] is not employed by active platform\n" \
1540 % (self
.MetaFile
, Arch
))
1543 self
.SourceDir
= self
.MetaFile
.SubDir
1544 self
.SourceOverrideDir
= None
1545 # use overrided path defined in DSC file
1546 if self
.MetaFile
.Key
in GlobalData
.gOverrideDir
:
1547 self
.SourceOverrideDir
= GlobalData
.gOverrideDir
[self
.MetaFile
.Key
]
1549 self
.ToolChain
= Toolchain
1550 self
.BuildTarget
= Target
1552 self
.ToolChainFamily
= self
.PlatformInfo
.ToolChainFamily
1553 self
.BuildRuleFamily
= self
.PlatformInfo
.BuildRuleFamily
1555 self
.IsMakeFileCreated
= False
1556 self
.IsCodeFileCreated
= False
1558 self
.BuildDatabase
= self
.Workspace
.BuildDatabase
1563 self
._Version
= None
1564 self
._ModuleType
= None
1565 self
._ComponentType
= None
1566 self
._PcdIsDriver
= None
1567 self
._AutoGenVersion
= None
1568 self
._LibraryFlag
= None
1569 self
._CustomMakefile
= None
1572 self
._BuildDir
= None
1573 self
._OutputDir
= None
1574 self
._DebugDir
= None
1575 self
._MakeFileDir
= None
1577 self
._IncludePathList
= None
1578 self
._AutoGenFileList
= None
1579 self
._UnicodeFileList
= None
1580 self
._SourceFileList
= None
1581 self
._ObjectFileList
= None
1582 self
._BinaryFileList
= None
1584 self
._DependentPackageList
= None
1585 self
._DependentLibraryList
= None
1586 self
._LibraryAutoGenList
= None
1587 self
._DerivedPackageList
= None
1588 self
._ModulePcdList
= None
1589 self
._LibraryPcdList
= None
1590 self
._GuidList
= None
1591 self
._ProtocolList
= None
1592 self
._PpiList
= None
1593 self
._DepexList
= None
1594 self
._DepexExpressionList
= None
1595 self
._BuildOption
= None
1596 self
._BuildTargets
= None
1597 self
._IntroBuildTargetList
= None
1598 self
._FinalBuildTargetList
= None
1599 self
._FileTypes
= None
1600 self
._BuildRules
= None
1605 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
1607 # Macros could be used in build_rule.txt (also Makefile)
1608 def _GetMacros(self
):
1609 if self
._Macro
== None:
1610 self
._Macro
= sdict()
1611 self
._Macro
["WORKSPACE" ] = self
.WorkspaceDir
1612 self
._Macro
["MODULE_NAME" ] = self
.Name
1613 self
._Macro
["MODULE_GUID" ] = self
.Guid
1614 self
._Macro
["MODULE_VERSION" ] = self
.Version
1615 self
._Macro
["MODULE_TYPE" ] = self
.ModuleType
1616 self
._Macro
["MODULE_FILE" ] = str(self
.MetaFile
)
1617 self
._Macro
["MODULE_FILE_BASE_NAME" ] = self
.MetaFile
.BaseName
1618 self
._Macro
["MODULE_RELATIVE_DIR" ] = self
.SourceDir
1619 self
._Macro
["MODULE_DIR" ] = self
.SourceDir
1621 self
._Macro
["BASE_NAME" ] = self
.Name
1623 self
._Macro
["ARCH" ] = self
.Arch
1624 self
._Macro
["TOOLCHAIN" ] = self
.ToolChain
1625 self
._Macro
["TOOLCHAIN_TAG" ] = self
.ToolChain
1626 self
._Macro
["TARGET" ] = self
.BuildTarget
1628 self
._Macro
["BUILD_DIR" ] = self
.PlatformInfo
.BuildDir
1629 self
._Macro
["BIN_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
1630 self
._Macro
["LIB_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
1631 self
._Macro
["MODULE_BUILD_DIR" ] = self
.BuildDir
1632 self
._Macro
["OUTPUT_DIR" ] = self
.OutputDir
1633 self
._Macro
["DEBUG_DIR" ] = self
.DebugDir
1636 ## Return the module build data object
1637 def _GetModule(self
):
1638 if self
._Module
== None:
1639 self
._Module
= self
.Workspace
.BuildDatabase
[self
.MetaFile
, self
.Arch
]
1642 ## Return the module name
1643 def _GetBaseName(self
):
1644 return self
.Module
.BaseName
1646 ## Return the module SourceOverridePath
1647 def _GetSourceOverridePath(self
):
1648 return self
.Module
.SourceOverridePath
1650 ## Return the module meta-file GUID
1652 return self
.Module
.Guid
1654 ## Return the module version
1655 def _GetVersion(self
):
1656 return self
.Module
.Version
1658 ## Return the module type
1659 def _GetModuleType(self
):
1660 return self
.Module
.ModuleType
1662 ## Return the component type (for R8.x style of module)
1663 def _GetComponentType(self
):
1664 return self
.Module
.ComponentType
1666 ## Return the build type
1667 def _GetBuildType(self
):
1668 return self
.Module
.BuildType
1670 ## Return the PCD_IS_DRIVER setting
1671 def _GetPcdIsDriver(self
):
1672 return self
.Module
.PcdIsDriver
1674 ## Return the autogen version, i.e. module meta-file version
1675 def _GetAutoGenVersion(self
):
1676 return self
.Module
.AutoGenVersion
1678 ## Check if the module is library or not
1679 def _IsLibrary(self
):
1680 if self
._LibraryFlag
== None:
1681 if self
.Module
.LibraryClass
!= None and self
.Module
.LibraryClass
!= []:
1682 self
._LibraryFlag
= True
1684 self
._LibraryFlag
= False
1685 return self
._LibraryFlag
1687 ## Return the directory to store intermediate files of the module
1688 def _GetBuildDir(self
):
1689 if self
._BuildDir
== None:
1690 self
._BuildDir
= path
.join(
1691 self
.PlatformInfo
.BuildDir
,
1694 self
.MetaFile
.BaseName
1696 CreateDirectory(self
._BuildDir
)
1697 return self
._BuildDir
1699 ## Return the directory to store the intermediate object files of the mdoule
1700 def _GetOutputDir(self
):
1701 if self
._OutputDir
== None:
1702 self
._OutputDir
= path
.join(self
.BuildDir
, "OUTPUT")
1703 CreateDirectory(self
._OutputDir
)
1704 return self
._OutputDir
1706 ## Return the directory to store auto-gened source files of the mdoule
1707 def _GetDebugDir(self
):
1708 if self
._DebugDir
== None:
1709 self
._DebugDir
= path
.join(self
.BuildDir
, "DEBUG")
1710 CreateDirectory(self
._DebugDir
)
1711 return self
._DebugDir
1713 ## Return the path of custom file
1714 def _GetCustomMakefile(self
):
1715 if self
._CustomMakefile
== None:
1716 self
._CustomMakefile
= {}
1717 for Type
in self
.Module
.CustomMakefile
:
1718 if Type
in gMakeTypeMap
:
1719 MakeType
= gMakeTypeMap
[Type
]
1722 if self
.SourceOverrideDir
!= None:
1723 File
= os
.path
.join(self
.SourceOverrideDir
, self
.Module
.CustomMakefile
[Type
])
1724 if not os
.path
.exists(File
):
1725 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
1727 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
1728 self
._CustomMakefile
[MakeType
] = File
1729 return self
._CustomMakefile
1731 ## Return the directory of the makefile
1733 # @retval string The directory string of module's makefile
1735 def _GetMakeFileDir(self
):
1736 return self
.BuildDir
1738 ## Return build command string
1740 # @retval string Build command string
1742 def _GetBuildCommand(self
):
1743 return self
.PlatformInfo
.BuildCommand
1745 ## Get object list of all packages the module and its dependent libraries belong to
1747 # @retval list The list of package object
1749 def _GetDerivedPackageList(self
):
1751 for M
in [self
.Module
] + self
.DependentLibraryList
:
1752 for Package
in M
.Packages
:
1753 if Package
in PackageList
:
1755 PackageList
.append(Package
)
1758 ## Merge dependency expression
1760 # @retval list The token list of the dependency expression after parsed
1762 def _GetDepexTokenList(self
):
1763 if self
._DepexList
== None:
1764 self
._DepexList
= {}
1765 if self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
1766 return self
._DepexList
1768 self
._DepexList
[self
.ModuleType
] = []
1770 for ModuleType
in self
._DepexList
:
1771 DepexList
= self
._DepexList
[ModuleType
]
1773 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
1775 for M
in [self
.Module
] + self
.DependentLibraryList
:
1777 for D
in M
.Depex
[self
.Arch
, ModuleType
]:
1779 DepexList
.append('AND')
1780 DepexList
.append('(')
1782 if DepexList
[-1] == 'END': # no need of a END at this time
1784 DepexList
.append(')')
1787 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexList
))
1788 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
1790 if len(DepexList
) > 0:
1791 EdkLogger
.verbose('')
1792 return self
._DepexList
1794 ## Merge dependency expression
1796 # @retval list The token list of the dependency expression after parsed
1798 def _GetDepexExpressionTokenList(self
):
1799 if self
._DepexExpressionList
== None:
1800 self
._DepexExpressionList
= {}
1801 if self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
1802 return self
._DepexExpressionList
1804 self
._DepexExpressionList
[self
.ModuleType
] = ''
1806 for ModuleType
in self
._DepexExpressionList
:
1807 DepexExpressionList
= self
._DepexExpressionList
[ModuleType
]
1809 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
1811 for M
in [self
.Module
] + self
.DependentLibraryList
:
1813 for D
in M
.DepexExpression
[self
.Arch
, ModuleType
]:
1814 if DepexExpressionList
!= '':
1815 DepexExpressionList
+= ' AND '
1816 DepexExpressionList
+= '('
1817 DepexExpressionList
+= D
1818 DepexExpressionList
= DepexExpressionList
.rstrip('END').strip()
1819 DepexExpressionList
+= ')'
1822 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexExpressionList
))
1823 if 'BEFORE' in DepexExpressionList
or 'AFTER' in DepexExpressionList
:
1825 if len(DepexExpressionList
) > 0:
1826 EdkLogger
.verbose('')
1827 self
._DepexExpressionList
[ModuleType
] = DepexExpressionList
1828 return self
._DepexExpressionList
1830 ## Return the list of specification version required for the module
1832 # @retval list The list of specification defined in module file
1834 def _GetSpecification(self
):
1835 return self
.Module
.Specification
1837 ## Tool option for the module build
1839 # @param PlatformInfo The object of PlatformBuildInfo
1840 # @retval dict The dict containing valid options
1842 def _GetModuleBuildOption(self
):
1843 if self
._BuildOption
== None:
1844 self
._BuildOption
= self
.PlatformInfo
.ApplyBuildOption(self
.Module
)
1845 return self
._BuildOption
1847 ## Return a list of files which can be built from source
1849 # What kind of files can be built is determined by build rules in
1850 # $(WORKSPACE)/Conf/build_rule.txt and toolchain family.
1852 def _GetSourceFileList(self
):
1853 if self
._SourceFileList
== None:
1854 self
._SourceFileList
= []
1855 for F
in self
.Module
.Sources
:
1857 if F
.TagName
!= "" and F
.TagName
!= self
.ToolChain
:
1858 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "The toolchain [%s] for processing file [%s] is found, "
1859 "but [%s] is needed" % (F
.TagName
, str(F
), self
.ToolChain
))
1861 # match tool chain family
1862 if F
.ToolChainFamily
!= "" and F
.ToolChainFamily
!= self
.ToolChainFamily
:
1865 "The file [%s] must be built by tools of [%s], " \
1866 "but current toolchain family is [%s]" \
1867 % (str(F
), F
.ToolChainFamily
, self
.ToolChainFamily
))
1870 # add the file path into search path list for file including
1871 if F
.Dir
not in self
.IncludePathList
and self
.AutoGenVersion
>= 0x00010005:
1872 self
.IncludePathList
.insert(0, F
.Dir
)
1873 self
._SourceFileList
.append(F
)
1874 self
._ApplyBuildRule
(F
, TAB_UNKNOWN_FILE
)
1875 return self
._SourceFileList
1877 ## Return the list of unicode files
1878 def _GetUnicodeFileList(self
):
1879 if self
._UnicodeFileList
== None:
1880 if TAB_UNICODE_FILE
in self
.FileTypes
:
1881 self
._UnicodeFileList
= self
.FileTypes
[TAB_UNICODE_FILE
]
1883 self
._UnicodeFileList
= []
1884 return self
._UnicodeFileList
1886 ## Return a list of files which can be built from binary
1888 # "Build" binary files are just to copy them to build directory.
1890 # @retval list The list of files which can be built later
1892 def _GetBinaryFiles(self
):
1893 if self
._BinaryFileList
== None:
1894 self
._BinaryFileList
= []
1895 for F
in self
.Module
.Binaries
:
1896 if F
.Target
not in ['COMMON', '*'] and F
.Target
!= self
.BuildTarget
:
1898 self
._BinaryFileList
.append(F
)
1899 self
._ApplyBuildRule
(F
, F
.Type
)
1900 return self
._BinaryFileList
1902 def _GetBuildRules(self
):
1903 if self
._BuildRules
== None:
1905 BuildRuleDatabase
= self
.PlatformInfo
.BuildRule
1906 for Type
in BuildRuleDatabase
.FileTypeList
:
1907 #first try getting build rule by BuildRuleFamily
1908 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.BuildRuleFamily
]
1910 # build type is always module type, but ...
1911 if self
.ModuleType
!= self
.BuildType
:
1912 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.BuildRuleFamily
]
1913 #second try getting build rule by ToolChainFamily
1915 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.ToolChainFamily
]
1917 # build type is always module type, but ...
1918 if self
.ModuleType
!= self
.BuildType
:
1919 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.ToolChainFamily
]
1922 RuleObject
= RuleObject
.Instantiate(self
.Macros
)
1923 BuildRules
[Type
] = RuleObject
1924 for Ext
in RuleObject
.SourceFileExtList
:
1925 BuildRules
[Ext
] = RuleObject
1926 self
._BuildRules
= BuildRules
1927 return self
._BuildRules
1929 def _ApplyBuildRule(self
, File
, FileType
):
1930 if self
._BuildTargets
== None:
1931 self
._IntroBuildTargetList
= set()
1932 self
._FinalBuildTargetList
= set()
1933 self
._BuildTargets
= {}
1934 self
._FileTypes
= {}
1940 while Index
< len(SourceList
):
1941 Source
= SourceList
[Index
]
1945 CreateDirectory(Source
.Dir
)
1947 if File
.IsBinary
and File
== Source
and self
._BinaryFileList
!= None and File
in self
._BinaryFileList
:
1948 RuleObject
= self
.BuildRules
[TAB_DEFAULT_BINARY_FILE
]
1949 elif FileType
in self
.BuildRules
:
1950 RuleObject
= self
.BuildRules
[FileType
]
1951 elif Source
.Ext
in self
.BuildRules
:
1952 RuleObject
= self
.BuildRules
[Source
.Ext
]
1954 # stop at no more rules
1956 self
._FinalBuildTargetList
.add(LastTarget
)
1959 FileType
= RuleObject
.SourceFileType
1960 if FileType
not in self
._FileTypes
:
1961 self
._FileTypes
[FileType
] = set()
1962 self
._FileTypes
[FileType
].add(Source
)
1964 # stop at STATIC_LIBRARY for library
1965 if self
.IsLibrary
and FileType
== TAB_STATIC_LIBRARY
:
1967 self
._FinalBuildTargetList
.add(LastTarget
)
1970 Target
= RuleObject
.Apply(Source
)
1973 self
._FinalBuildTargetList
.add(LastTarget
)
1975 elif not Target
.Outputs
:
1976 # Only do build for target with outputs
1977 self
._FinalBuildTargetList
.add(Target
)
1979 if FileType
not in self
._BuildTargets
:
1980 self
._BuildTargets
[FileType
] = set()
1981 self
._BuildTargets
[FileType
].add(Target
)
1983 if not Source
.IsBinary
and Source
== File
:
1984 self
._IntroBuildTargetList
.add(Target
)
1986 # to avoid cyclic rule
1987 if FileType
in RuleChain
:
1990 RuleChain
.append(FileType
)
1991 SourceList
.extend(Target
.Outputs
)
1993 FileType
= TAB_UNKNOWN_FILE
1995 def _GetTargets(self
):
1996 if self
._BuildTargets
== None:
1997 self
._IntroBuildTargetList
= set()
1998 self
._FinalBuildTargetList
= set()
1999 self
._BuildTargets
= {}
2000 self
._FileTypes
= {}
2002 #TRICK: call _GetSourceFileList to apply build rule for binary files
2003 if self
.SourceFileList
:
2006 #TRICK: call _GetBinaryFileList to apply build rule for binary files
2007 if self
.BinaryFileList
:
2010 return self
._BuildTargets
2012 def _GetIntroTargetList(self
):
2014 return self
._IntroBuildTargetList
2016 def _GetFinalTargetList(self
):
2018 return self
._FinalBuildTargetList
2020 def _GetFileTypes(self
):
2022 return self
._FileTypes
2024 ## Get the list of package object the module depends on
2026 # @retval list The package object list
2028 def _GetDependentPackageList(self
):
2029 return self
.Module
.Packages
2031 ## Return the list of auto-generated code file
2033 # @retval list The list of auto-generated file
2035 def _GetAutoGenFileList(self
):
2036 UniStringAutoGenC
= True
2037 UniStringBinBuffer
= None
2038 if self
.BuildType
== 'UEFI_HII':
2039 UniStringBinBuffer
= StringIO()
2040 UniStringAutoGenC
= False
2041 if self
._AutoGenFileList
== None:
2042 self
._AutoGenFileList
= {}
2043 AutoGenC
= TemplateString()
2044 AutoGenH
= TemplateString()
2045 StringH
= TemplateString()
2046 GenC
.CreateCode(self
, AutoGenC
, AutoGenH
, StringH
, UniStringAutoGenC
, UniStringBinBuffer
)
2047 if str(AutoGenC
) != "" and TAB_C_CODE_FILE
in self
.FileTypes
:
2048 AutoFile
= PathClass(gAutoGenCodeFileName
, self
.DebugDir
)
2049 self
._AutoGenFileList
[AutoFile
] = str(AutoGenC
)
2050 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
2051 if str(AutoGenH
) != "":
2052 AutoFile
= PathClass(gAutoGenHeaderFileName
, self
.DebugDir
)
2053 self
._AutoGenFileList
[AutoFile
] = str(AutoGenH
)
2054 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
2055 if str(StringH
) != "":
2056 AutoFile
= PathClass(gAutoGenStringFileName
% {"module_name":self
.Name
}, self
.DebugDir
)
2057 self
._AutoGenFileList
[AutoFile
] = str(StringH
)
2058 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
2059 if UniStringBinBuffer
!= None and UniStringBinBuffer
.getvalue() != "":
2060 AutoFile
= PathClass(gAutoGenStringFormFileName
% {"module_name":self
.Name
}, self
.OutputDir
)
2061 self
._AutoGenFileList
[AutoFile
] = UniStringBinBuffer
.getvalue()
2062 AutoFile
.IsBinary
= True
2063 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
2064 if UniStringBinBuffer
!= None:
2065 UniStringBinBuffer
.close()
2066 return self
._AutoGenFileList
2068 ## Return the list of library modules explicitly or implicityly used by this module
2069 def _GetLibraryList(self
):
2070 if self
._DependentLibraryList
== None:
2071 # only merge library classes and PCD for non-library module
2073 self
._DependentLibraryList
= []
2075 if self
.AutoGenVersion
< 0x00010005:
2076 self
._DependentLibraryList
= self
.PlatformInfo
.ResolveLibraryReference(self
.Module
)
2078 self
._DependentLibraryList
= self
.PlatformInfo
.ApplyLibraryInstance(self
.Module
)
2079 return self
._DependentLibraryList
2081 ## Get the list of PCDs from current module
2083 # @retval list The list of PCD
2085 def _GetModulePcdList(self
):
2086 if self
._ModulePcdList
== None:
2087 # apply PCD settings from platform
2088 self
._ModulePcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, self
.Module
.Pcds
)
2089 return self
._ModulePcdList
2091 ## Get the list of PCDs from dependent libraries
2093 # @retval list The list of PCD
2095 def _GetLibraryPcdList(self
):
2096 if self
._LibraryPcdList
== None:
2098 if not self
.IsLibrary
:
2099 # get PCDs from dependent libraries
2100 for Library
in self
.DependentLibraryList
:
2101 for Key
in Library
.Pcds
:
2102 # skip duplicated PCDs
2103 if Key
in self
.Module
.Pcds
or Key
in Pcds
:
2105 Pcds
[Key
] = copy
.copy(Library
.Pcds
[Key
])
2106 # apply PCD settings from platform
2107 self
._LibraryPcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, Pcds
)
2109 self
._LibraryPcdList
= []
2110 return self
._LibraryPcdList
2112 ## Get the GUID value mapping
2114 # @retval dict The mapping between GUID cname and its value
2116 def _GetGuidList(self
):
2117 if self
._GuidList
== None:
2118 self
._GuidList
= self
.Module
.Guids
2119 for Library
in self
.DependentLibraryList
:
2120 self
._GuidList
.update(Library
.Guids
)
2121 return self
._GuidList
2123 ## Get the protocol value mapping
2125 # @retval dict The mapping between protocol cname and its value
2127 def _GetProtocolList(self
):
2128 if self
._ProtocolList
== None:
2129 self
._ProtocolList
= self
.Module
.Protocols
2130 for Library
in self
.DependentLibraryList
:
2131 self
._ProtocolList
.update(Library
.Protocols
)
2132 return self
._ProtocolList
2134 ## Get the PPI value mapping
2136 # @retval dict The mapping between PPI cname and its value
2138 def _GetPpiList(self
):
2139 if self
._PpiList
== None:
2140 self
._PpiList
= self
.Module
.Ppis
2141 for Library
in self
.DependentLibraryList
:
2142 self
._PpiList
.update(Library
.Ppis
)
2143 return self
._PpiList
2145 ## Get the list of include search path
2147 # @retval list The list path
2149 def _GetIncludePathList(self
):
2150 if self
._IncludePathList
== None:
2151 self
._IncludePathList
= []
2152 if self
.AutoGenVersion
< 0x00010005:
2153 for Inc
in self
.Module
.Includes
:
2154 if Inc
not in self
._IncludePathList
:
2155 self
._IncludePathList
.append(Inc
)
2157 Inc
= path
.join(Inc
, self
.Arch
.capitalize())
2158 if os
.path
.exists(Inc
) and Inc
not in self
._IncludePathList
:
2159 self
._IncludePathList
.append(Inc
)
2160 # r8 module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
2161 self
._IncludePathList
.append(self
.DebugDir
)
2163 self
._IncludePathList
.append(self
.MetaFile
.Dir
)
2164 self
._IncludePathList
.append(self
.DebugDir
)
2166 for Package
in self
.Module
.Packages
:
2167 PackageDir
= path
.join(self
.WorkspaceDir
, Package
.MetaFile
.Dir
)
2168 if PackageDir
not in self
._IncludePathList
:
2169 self
._IncludePathList
.append(PackageDir
)
2170 for Inc
in Package
.Includes
:
2171 if Inc
not in self
._IncludePathList
:
2172 self
._IncludePathList
.append(str(Inc
))
2173 return self
._IncludePathList
2175 ## Create makefile for the module and its dependent libraries
2177 # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of
2178 # dependent libraries will be created
2180 def CreateMakeFile(self
, CreateLibraryMakeFile
=True):
2181 if self
.IsMakeFileCreated
:
2184 if not self
.IsLibrary
and CreateLibraryMakeFile
:
2185 for LibraryAutoGen
in self
.LibraryAutoGenList
:
2186 LibraryAutoGen
.CreateMakeFile()
2188 if len(self
.CustomMakefile
) == 0:
2189 Makefile
= GenMake
.ModuleMakefile(self
)
2191 Makefile
= GenMake
.CustomMakefile(self
)
2192 if Makefile
.Generate():
2193 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for module %s [%s]" %
2194 (self
.Name
, self
.Arch
))
2196 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for module %s [%s]" %
2197 (self
.Name
, self
.Arch
))
2199 self
.IsMakeFileCreated
= True
2201 ## Create autogen code for the module and its dependent libraries
2203 # @param CreateLibraryCodeFile Flag indicating if or not the code of
2204 # dependent libraries will be created
2206 def CreateCodeFile(self
, CreateLibraryCodeFile
=True):
2207 if self
.IsCodeFileCreated
:
2210 if not self
.IsLibrary
and CreateLibraryCodeFile
:
2211 for LibraryAutoGen
in self
.LibraryAutoGenList
:
2212 LibraryAutoGen
.CreateCodeFile()
2215 IgoredAutoGenList
= []
2217 for File
in self
.AutoGenFileList
:
2218 if GenC
.Generate(File
.Path
, self
.AutoGenFileList
[File
], File
.IsBinary
):
2219 #Ignore R8 AutoGen.c
2220 if self
.AutoGenVersion
< 0x00010005 and File
.Name
== 'AutoGen.c':
2223 AutoGenList
.append(str(File
))
2225 IgoredAutoGenList
.append(str(File
))
2227 # Skip the following code for EDK I inf
2228 if self
.AutoGenVersion
< 0x00010005:
2231 for ModuleType
in self
.DepexList
:
2232 if len(self
.DepexList
[ModuleType
]) == 0:
2234 Dpx
= GenDepex
.DependencyExpression(self
.DepexList
[ModuleType
], ModuleType
, True)
2235 DpxFile
= gAutoGenDepexFileName
% {"module_name" : self
.Name
}
2237 if Dpx
.Generate(path
.join(self
.OutputDir
, DpxFile
)):
2238 AutoGenList
.append(str(DpxFile
))
2240 IgoredAutoGenList
.append(str(DpxFile
))
2242 if IgoredAutoGenList
== []:
2243 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] files for module %s [%s]" %
2244 (" ".join(AutoGenList
), self
.Name
, self
.Arch
))
2245 elif AutoGenList
== []:
2246 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of [%s] files for module %s [%s]" %
2247 (" ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
2249 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] (skipped %s) files for module %s [%s]" %
2250 (" ".join(AutoGenList
), " ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
2252 self
.IsCodeFileCreated
= True
2255 ## Summarize the ModuleAutoGen objects of all libraries used by this module
2256 def _GetLibraryAutoGenList(self
):
2257 if self
._LibraryAutoGenList
== None:
2258 self
._LibraryAutoGenList
= []
2259 for Library
in self
.DependentLibraryList
:
2266 self
.PlatformInfo
.MetaFile
2268 if La
not in self
._LibraryAutoGenList
:
2269 self
._LibraryAutoGenList
.append(La
)
2270 for Lib
in La
.CodaTargetList
:
2271 self
._ApplyBuildRule
(Lib
.Target
, TAB_UNKNOWN_FILE
)
2272 return self
._LibraryAutoGenList
2274 ## Return build command string
2276 # @retval string Build command string
2278 def _GetBuildCommand(self
):
2279 return self
.PlatformInfo
.BuildCommand
2282 Module
= property(_GetModule
)
2283 Name
= property(_GetBaseName
)
2284 Guid
= property(_GetGuid
)
2285 Version
= property(_GetVersion
)
2286 ModuleType
= property(_GetModuleType
)
2287 ComponentType
= property(_GetComponentType
)
2288 BuildType
= property(_GetBuildType
)
2289 PcdIsDriver
= property(_GetPcdIsDriver
)
2290 AutoGenVersion
= property(_GetAutoGenVersion
)
2291 Macros
= property(_GetMacros
)
2292 Specification
= property(_GetSpecification
)
2294 IsLibrary
= property(_IsLibrary
)
2296 BuildDir
= property(_GetBuildDir
)
2297 OutputDir
= property(_GetOutputDir
)
2298 DebugDir
= property(_GetDebugDir
)
2299 MakeFileDir
= property(_GetMakeFileDir
)
2300 CustomMakefile
= property(_GetCustomMakefile
)
2302 IncludePathList
= property(_GetIncludePathList
)
2303 AutoGenFileList
= property(_GetAutoGenFileList
)
2304 UnicodeFileList
= property(_GetUnicodeFileList
)
2305 SourceFileList
= property(_GetSourceFileList
)
2306 BinaryFileList
= property(_GetBinaryFiles
) # FileType : [File List]
2307 Targets
= property(_GetTargets
)
2308 IntroTargetList
= property(_GetIntroTargetList
)
2309 CodaTargetList
= property(_GetFinalTargetList
)
2310 FileTypes
= property(_GetFileTypes
)
2311 BuildRules
= property(_GetBuildRules
)
2313 DependentPackageList
= property(_GetDependentPackageList
)
2314 DependentLibraryList
= property(_GetLibraryList
)
2315 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
2316 DerivedPackageList
= property(_GetDerivedPackageList
)
2318 ModulePcdList
= property(_GetModulePcdList
)
2319 LibraryPcdList
= property(_GetLibraryPcdList
)
2320 GuidList
= property(_GetGuidList
)
2321 ProtocolList
= property(_GetProtocolList
)
2322 PpiList
= property(_GetPpiList
)
2323 DepexList
= property(_GetDepexTokenList
)
2324 DepexExpressionList
= property(_GetDepexExpressionTokenList
)
2325 BuildOption
= property(_GetModuleBuildOption
)
2326 BuildCommand
= property(_GetBuildCommand
)
2328 # This acts like the main() function for the script, unless it is 'import'ed into another script.
2329 if __name__
== '__main__':