1 # Copyright (c) 2007, Intel Corporation
\r
2 # All rights reserved. This program and the accompanying materials
\r
3 # are licensed and made available under the terms and conditions of the BSD License
\r
4 # which accompanies this distribution. The full text of the license may be found at
\r
5 # http://opensource.org/licenses/bsd-license.php
\r
7 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
8 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
11 # This file is used to define each component of the build database
\r
17 import os, string, copy, pdb, copy
\r
20 from InfClassObject import *
\r
21 from DecClassObject import *
\r
22 from DscClassObject import *
\r
23 from String import *
\r
24 from BuildToolError import *
\r
25 from Misc import sdict
\r
26 from CommonDataClass.CommonClass import *
\r
29 # This Class is used for PcdObject
\r
31 class PcdClassObject(object):
\r
32 def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, IsOverrided = False):
\r
33 self.TokenCName = Name
\r
34 self.TokenSpaceGuidCName = Guid
\r
36 self.DatumType = DatumType
\r
37 self.DefaultValue = Value
\r
38 self.TokenValue = Token
\r
39 self.MaxDatumSize = MaxDatumSize
\r
40 self.SkuInfoList = SkuInfoList
\r
41 self.IsOverrided = IsOverrided
\r
45 rtn = '\tTokenCName=' + str(self.TokenCName) + ', ' + \
\r
46 'TokenSpaceGuidCName=' + str(self.TokenSpaceGuidCName) + ', ' + \
\r
47 'Type=' + str(self.Type) + ', ' + \
\r
48 'DatumType=' + str(self.DatumType) + ', ' + \
\r
49 'DefaultValue=' + str(self.DefaultValue) + ', ' + \
\r
50 'TokenValue=' + str(self.TokenValue) + ', ' + \
\r
51 'MaxDatumSize=' + str(self.MaxDatumSize) + ', '
\r
52 for Item in self.SkuInfoList.values():
\r
53 rtn = rtn + 'SkuId=' + Item.SkuId + ', ' + 'SkuIdName=' + Item.SkuIdName
\r
54 rtn = rtn + str(self.IsOverrided)
\r
58 def __eq__(self, other):
\r
59 return other != None and self.TokenCName == other.TokenCName and self.TokenSpaceGuidCName == other.TokenSpaceGuidCName
\r
62 return hash((self.TokenCName, self.TokenSpaceGuidCName))
\r
65 # This Class is used for LibraryClassObject
\r
67 class LibraryClassObject(object):
\r
68 def __init__(self, Name = None, SupModList = [], Type = None):
\r
69 self.LibraryClass = Name
\r
70 self.SupModList = SupModList
\r
72 self.SupModList = CleanString(Type).split(DataType.TAB_SPACE_SPLIT)
\r
74 class ModuleBuildClassObject(object):
\r
76 self.DescFilePath = ''
\r
78 self.ModuleType = ''
\r
81 self.PcdIsDriver = ''
\r
82 self.BinaryModule = ''
\r
83 self.CustomMakefile = {}
\r
84 self.Specification = {}
\r
85 self.LibraryClass = [] # [ LibraryClassObject, ...]
\r
86 self.ModuleEntryPointList = []
\r
87 self.ModuleUnloadImageList = []
\r
88 self.ConstructorList = []
\r
89 self.DestructorList = []
\r
91 self.Binaries = [] #[ ModuleBinaryClassObject, ...]
\r
92 self.Sources = [] #[ ModuleSourceFilesClassObject, ... ]
\r
93 self.LibraryClasses = {} #{ [LibraryClassName, ModuleType] : LibraryClassInfFile }
\r
94 self.Protocols = [] #[ ProtocolName, ... ]
\r
95 self.Ppis = [] #[ PpiName, ... ]
\r
96 self.Guids = [] #[ GuidName, ... ]
\r
97 self.Includes = [] #[ IncludePath, ... ]
\r
98 self.Packages = [] #[ DecFileName, ... ]
\r
99 self.Pcds = {} #{ [(PcdCName, PcdGuidCName)] : PcdClassObject}
\r
100 self.BuildOptions = {} #{ [BuildOptionKey] : BuildOptionValue}
\r
104 return self.DescFilePath
\r
106 def __eq__(self, other):
\r
107 return self.DescFilePath == str(other)
\r
109 def __hash__(self):
\r
110 return hash(self.DescFilePath)
\r
112 class PackageBuildClassObject(object):
\r
113 def __init__(self):
\r
114 self.DescFilePath = ''
\r
115 self.PackageName = ''
\r
119 self.Protocols = {} #{ [ProtocolName] : Protocol Guid, ... }
\r
120 self.Ppis = {} #{ [PpiName] : Ppi Guid, ... }
\r
121 self.Guids = {} #{ [GuidName] : Guid, ... }
\r
122 self.Includes = [] #[ IncludePath, ... ]
\r
123 self.LibraryClasses = {} #{ [LibraryClassName] : LibraryClassInfFile }
\r
124 self.Pcds = {} #{ [(PcdCName, PcdGuidCName)] : PcdClassObject}
\r
127 return self.DescFilePath
\r
129 def __eq__(self, other):
\r
130 return self.DescFilePath == str(other)
\r
132 def __hash__(self):
\r
133 return hash(self.DescFilePath)
\r
135 class PlatformBuildClassObject(object):
\r
136 def __init__(self):
\r
137 self.DescFilePath = ''
\r
138 self.PlatformName = ''
\r
141 self.DscSpecification = ''
\r
142 self.OutputDirectory = ''
\r
143 self.FlashDefinition = ''
\r
144 self.BuildNumber = ''
\r
145 self.MakefileName = ''
\r
147 self.SkuIds = {} #{ 'SkuName' : SkuId, '!include' : includefilename, ...}
\r
148 self.Modules = [] #[ InfFileName, ... ]
\r
149 self.Libraries = [] #[ InfFileName, ... ]
\r
150 self.LibraryClasses = {} #{ (LibraryClassName, ModuleType) : LibraryClassInfFile }
\r
151 self.Pcds = {} #{ [(PcdCName, PcdGuidCName)] : PcdClassObject }
\r
152 self.BuildOptions = {} #{ [BuildOptionKey] : BuildOptionValue }
\r
155 return self.DescFilePath
\r
157 def __eq__(self, other):
\r
158 return self.DescFilePath == str(other)
\r
160 def __hash__(self):
\r
161 return hash(self.DescFilePath)
\r
163 class ItemBuild(object):
\r
164 def __init__(self, Arch, Platform = None, Package = None, Module = None):
\r
166 self.PlatformDatabase = {} #{ [DscFileName] : PlatformBuildClassObject, ...}
\r
167 self.PackageDatabase = {} #{ [DecFileName] : PacakgeBuildClassObject, ...}
\r
168 self.ModuleDatabase = {} #{ [InfFileName] : ModuleBuildClassObject, ...}
\r
171 # This class is used to parse active platform to init all inf/dec/dsc files
\r
172 # Generate module/package/platform databases for build
\r
174 class WorkspaceBuild(object):
\r
175 def __init__(self, ActivePlatform, WorkspaceDir):
\r
176 self.WorkspaceDir = NormPath(WorkspaceDir)
\r
177 self.SupArchList = [] #[ 'IA32', 'X64', ...]
\r
178 self.BuildTarget = [] #[ 'RELEASE', 'DEBUG']
\r
181 self.FdTargetList = []
\r
182 self.FvTargetList = []
\r
183 self.TargetTxt = None
\r
184 self.ToolDef = None
\r
186 self.InfDatabase = {} #{ [InfFileName] : InfClassObject}
\r
187 self.DecDatabase = {} #{ [DecFileName] : DecClassObject}
\r
188 self.DscDatabase = {} #{ [DscFileName] : DscClassObject}
\r
191 # Init build for all arches
\r
194 for Arch in DataType.ARCH_LIST:
\r
195 self.Build[Arch] = ItemBuild(Arch)
\r
198 # Get active platform
\r
200 DscFileName = NormPath(ActivePlatform)
\r
201 File = self.WorkspaceFile(DscFileName)
\r
202 if os.path.exists(File) and os.path.isfile(File):
\r
203 self.DscDatabase[DscFileName] = Dsc(File, True, True, self.WorkspaceDir)
\r
205 EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData = File)
\r
208 # Parse platform to get module
\r
210 for DscFile in self.DscDatabase.keys():
\r
211 Platform = self.DscDatabase[DscFile].Platform
\r
214 # Get global information
\r
216 self.SupArchList = Platform.Header.SupArchList
\r
217 self.BuildTarget = Platform.Header.BuildTargets
\r
218 self.SkuId = Platform.Header.SkuIdName
\r
219 self.Fdf = NormPath(Platform.FlashDefinitionFile.FilePath)
\r
222 # Get all inf files
\r
224 for Item in Platform.LibraryClasses.LibraryList:
\r
225 for Arch in Item.SupArchList:
\r
226 self.AddToInfDatabase(Item.FilePath)
\r
228 for Item in Platform.Modules.ModuleList:
\r
229 for Arch in Item.SupArchList:
\r
233 Module = Item.FilePath
\r
234 self.AddToInfDatabase(Module)
\r
236 # Add library used in modules
\r
238 for Lib in Item.LibraryClasses.LibraryList:
\r
239 self.AddToInfDatabase(Lib.FilePath)
\r
240 self.UpdateLibraryClassOfModule(Module, Lib.Name, Arch, Lib.FilePath)
\r
243 # Parse module to get package
\r
245 for InfFile in self.InfDatabase.keys():
\r
246 Module = self.InfDatabase[InfFile].Module
\r
250 for Item in Module.PackageDependencies:
\r
251 for Arch in Item.SupArchList:
\r
252 self.AddToDecDatabase(Item.FilePath)
\r
253 # End of self.Init()
\r
256 # Generate PlatformDatabase
\r
258 def GenPlatformDatabase(self):
\r
259 for Dsc in self.DscDatabase.keys():
\r
260 Platform = self.DscDatabase[Dsc].Platform
\r
262 for Arch in self.SupArchList:
\r
263 pb = PlatformBuildClassObject()
\r
266 pb.DescFilePath = Dsc
\r
267 pb.PlatformName = Platform.Header.Name
\r
268 pb.Guid = Platform.Header.Guid
\r
269 pb.Version = Platform.Header.Version
\r
270 pb.DscSpecification = Platform.Header.DscSpecification
\r
271 pb.OutputDirectory = NormPath(Platform.Header.OutputDirectory)
\r
272 pb.FlashDefinition = NormPath(Platform.FlashDefinitionFile.FilePath)
\r
273 pb.BuildNumber = Platform.Header.BuildNumber
\r
276 for Key in Platform.SkuInfos.SkuInfoList.keys():
\r
277 pb.SkuIds[Key] = Platform.SkuInfos.SkuInfoList[Key]
\r
280 for Item in Platform.Modules.ModuleList:
\r
281 if Arch in Item.SupArchList:
\r
282 pb.Modules.append(NormPath(Item.FilePath))
\r
285 for Item in Platform.BuildOptions.BuildOptionList:
\r
286 if Arch in Item.SupArchList:
\r
287 pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option
\r
290 for Item in Platform.LibraryClasses.LibraryList:
\r
291 SupModuleList = self.FindSupModuleListOfLibraryClass(Item, Platform.LibraryClasses.LibraryList)
\r
292 if Arch in Item.SupArchList:
\r
293 for ModuleType in SupModuleList:
\r
294 pb.LibraryClasses[(Item.Name, ModuleType)] = NormPath(Item.FilePath)
\r
297 for Item in Platform.DynamicPcdBuildDefinitions:
\r
298 if Arch in Item.SupArchList:
\r
300 Guid = Item.TokenSpaceGuidCName
\r
301 Type = Item.ItemType
\r
302 DatumType = Item.DatumType
\r
303 Value = Item.DefaultValue
\r
305 MaxDatumSize = Item.MaxDatumSize
\r
306 SkuInfoList = Item.SkuInfoList
\r
307 pb.Pcds[(Name, Guid)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False)
\r
310 self.Build[Arch].PlatformDatabase[Dsc] = pb
\r
314 # Generate PackageDatabase
\r
316 def GenPackageDatabase(self):
\r
317 for Dec in self.DecDatabase.keys():
\r
318 Package = self.DecDatabase[Dec].Package
\r
320 for Arch in self.SupArchList:
\r
321 pb = PackageBuildClassObject()
\r
324 pb.DescFilePath = Dec
\r
325 pb.PackageName = Package.Header.Name
\r
326 pb.Guid = Package.Header.Guid
\r
327 pb.Version = Package.Header.Version
\r
330 for Item in Package.ProtocolDeclarations:
\r
331 if Arch in Item.SupArchList:
\r
332 pb.Protocols[Item.CName] = Item.Guid
\r
335 for Item in Package.PpiDeclarations:
\r
336 if Arch in Item.SupArchList:
\r
337 pb.Ppis[Item.CName] = Item.Guid
\r
340 for Item in Package.GuidDeclarations:
\r
341 if Arch in Item.SupArchList:
\r
342 pb.Ppis[Item.CName] = Item.Guid
\r
345 for Item in Package.Includes:
\r
346 if Arch in Item.SupArchList:
\r
347 pb.Includes.append(NormPath(Item.FilePath))
\r
350 for Item in Package.LibraryClassDeclarations:
\r
351 if Arch in Item.SupArchList:
\r
352 pb.LibraryClasses[Item.LibraryClass] = NormPath(Item.RecommendedInstance)
\r
355 for Item in Package.PcdDeclarations:
\r
356 if Arch in Item.SupArchList:
\r
358 Guid = Item.TokenSpaceGuidCName
\r
359 Type = Item.ItemType
\r
360 DatumType = Item.DatumType
\r
361 Value = Item.DefaultValue
\r
363 MaxDatumSize = Item.MaxDatumSize
\r
364 SkuInfoList = Item.SkuInfoList
\r
365 pb.Pcds[(Name, Guid)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False)
\r
368 self.Build[Arch].PackageDatabase[Dec] = pb
\r
372 # Generate ModuleDatabase
\r
374 def GenModuleDatabase(self, PcdsSet = {}, InfList = []):
\r
375 for Inf in self.InfDatabase.keys():
\r
376 Module = self.InfDatabase[Inf].Module
\r
378 for Arch in self.SupArchList:
\r
379 if not self.IsModuleDefinedInPlatform(Inf, Arch, InfList):
\r
382 pb = ModuleBuildClassObject()
\r
385 pb.DescFilePath = Inf
\r
386 pb.BaseName = Module.Header.Name
\r
387 pb.Guid = Module.Header.Guid
\r
388 pb.Version = Module.Header.Version
\r
389 pb.ModuleType = Module.Header.ModuleType
\r
390 pb.PcdIsDriver = Module.Header.PcdIsDriver
\r
391 pb.BinaryModule = Module.Header.BinaryModule
\r
392 pb.CustomMakefile = Module.Header.CustomMakefile
\r
395 pb.Specification = Module.Header.Specification
\r
396 pb.Specification[TAB_INF_DEFINES_EDK_RELEASE_VERSION] = Module.Header.EdkReleaseVersion
\r
397 pb.Specification[TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION] = Module.Header.EfiSpecificationVersion
\r
399 # LibraryClass of Defines
\r
400 for Item in Module.Header.LibraryClass:
\r
401 pb.LibraryClass.append(LibraryClassObject(Item.LibraryClass, Item.SupModuleList, None))
\r
403 # Module image and library of Defines
\r
404 for Item in Module.ExternImages:
\r
405 if Item.ModuleEntryPoint != '':
\r
406 pb.ModuleEntryPointList.append(Item.ModuleEntryPoint)
\r
407 if Item.ModuleUnloadImage != '':
\r
408 pb.ModuleUnloadImageList.append(Item.ModuleUnloadImage)
\r
409 for Item in Module.ExternLibraries:
\r
410 if Item.Constructor != '':
\r
411 pb.ConstructorList.append(Item.Constructor)
\r
412 if Item.Destructor != '':
\r
413 pb.DestructorList.append(Item.Destructor)
\r
416 for Item in Module.Binaries:
\r
417 if Arch in Item.SupArchList:
\r
418 FileName = NormPath(Item.BinaryFile)
\r
419 FileType = Item.FileType
\r
420 Target = Item.Target
\r
421 FeatureFlag = Item.FeatureFlag
\r
422 pb.Binaries.append(ModuleBinaryFileClass(FileName, FileType, Target, FeatureFlag))
\r
425 for Item in Module.Sources:
\r
426 if Arch in Item.SupArchList:
\r
427 SourceFile = NormPath(Item.SourceFile)
\r
428 TagName = Item.TagName
\r
429 ToolCode = Item.ToolCode
\r
430 ToolChainFamily = Item.ToolChainFamily
\r
431 FeatureFlag = Item.FeatureFlag
\r
432 pb.Sources.append(ModuleSourceFileClass(SourceFile, TagName, ToolCode, ToolChainFamily, FeatureFlag))
\r
435 for Item in Module.Protocols:
\r
436 if Arch in Item.SupArchList:
\r
437 pb.Protocols.append(Item.CName)
\r
440 for Item in Module.Ppis:
\r
441 if Arch in Item.SupArchList:
\r
442 pb.Ppis.append(Item.CName)
\r
445 for Item in Module.Guids:
\r
446 if Arch in Item.SupArchList:
\r
447 pb.Ppis.append(Item.CName)
\r
450 for Item in Module.Includes:
\r
451 if Arch in Item.SupArchList:
\r
452 pb.Includes.append(NormPath(Item.FilePath))
\r
455 for Item in Module.PackageDependencies:
\r
456 if Arch in Item.SupArchList:
\r
457 pb.Packages.append(NormPath(Item.FilePath))
\r
460 for Item in Module.BuildOptions:
\r
461 if Arch in Item.SupArchList:
\r
462 pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option
\r
463 self.FindBuildOptions(Arch, Inf, pb.BuildOptions)
\r
466 for Item in Module.Depex:
\r
467 if Arch in Item.SupArchList:
\r
468 pb.Depex = pb.Depex + Item.Depex + ' '
\r
469 pb.Depex = pb.Depex.strip()
\r
472 for Item in Module.LibraryClasses:
\r
473 if Arch in Item.SupArchList:
\r
474 Lib = Item.LibraryClass
\r
475 RecommendedInstance = Item.RecommendedInstance
\r
476 if pb.LibraryClass != []:
\r
478 for Libs in pb.LibraryClass:
\r
479 for Type in Libs.SupModList:
\r
480 Instance = self.FindLibraryClassInstanceOfLibrary(Lib, Arch, Type)
\r
481 if Instance == None:
\r
482 Instance = RecommendedInstance
\r
483 pb.LibraryClasses[(Lib, Type)] = NormPath(Instance)
\r
486 Instance = self.FindLibraryClassInstanceOfModule(Lib, Arch, pb.ModuleType, Inf)
\r
487 if Instance == None:
\r
488 Instance = RecommendedInstance
\r
489 pb.LibraryClasses[(Lib, pb.ModuleType)] = NormPath(Instance)
\r
492 for Item in Module.PcdCodes:
\r
493 if Arch in Item.SupArchList:
\r
495 Guid = Item.TokenSpaceGuidCName
\r
496 Type = Item.ItemType
\r
497 pb.Pcds[(Name, Guid)] = self.FindPcd(Arch, Inf, Name, Guid, Type, PcdsSet)
\r
500 self.Build[Arch].ModuleDatabase[Inf] = pb
\r
504 # Update Libraries Of Platform Database
\r
506 def UpdateLibrariesOfPlatform(self, InfList = []):
\r
507 for Arch in self.SupArchList:
\r
508 PlatformDatabase = self.Build[Arch].PlatformDatabase
\r
509 for Dsc in PlatformDatabase:
\r
510 Platform = PlatformDatabase[Dsc]
\r
511 for Inf in Platform.Modules:
\r
512 if not self.IsModuleDefinedInPlatform(Inf, Arch, InfList):
\r
514 Module = self.Build[Arch].ModuleDatabase[NormPath(Inf)]
\r
515 if Module.LibraryClass == None or Module.LibraryClass == []:
\r
516 self.UpdateLibrariesOfModule(Module, Arch)
\r
517 for Key in Module.LibraryClasses:
\r
518 Lib = Module.LibraryClasses[Key]
\r
519 if Lib not in Platform.Libraries:
\r
520 Platform.Libraries.append(Lib)
\r
521 ## Stack = [NormPath(str(Module))]
\r
523 ## while len(Stack) > 0:
\r
524 ## M = self.Build[Arch].ModuleDatabase[Stack.pop()]
\r
525 ## for Key, Lib in M.LibraryClasses.iteritems():
\r
526 ## if Module.ModuleType not in Key or Lib == None or Lib == "":
\r
528 ## Lib = NormPath(Lib)
\r
529 ## if Lib not in Platform.Libraries:
\r
530 ## Platform.Libraries.append(Lib)
\r
531 ## if Lib not in Libs:
\r
532 ## Libs.append(Lib)
\r
533 ## Stack.append(Lib)
\r
535 def UpdateLibrariesOfModule(self, Module, Arch):
\r
536 ModuleDatabase = self.Build[Arch].ModuleDatabase
\r
538 ModuleType = Module.ModuleType
\r
539 LibraryConsumerList = [Module]
\r
542 ConsumedByList = sdict()
\r
543 LibraryInstance = sdict()
\r
545 EdkLogger.verbose("")
\r
546 EdkLogger.verbose("Library instances of module [%s]:" % str(Module))
\r
547 while len(LibraryConsumerList) > 0:
\r
548 module = LibraryConsumerList.pop()
\r
549 for Key, LibraryPath in module.LibraryClasses.iteritems():
\r
550 # The "Key" is in format of (library_class_name, supported_module_type)
\r
551 LibraryClassName = Key[0]
\r
552 if ModuleType != "USER_DEFINED" and ModuleType not in Key:
\r
553 EdkLogger.debug(EdkLogger.DEBUG_3, "%s for module type %s is not supported (%s)" % (Key + (LibraryPath,)))
\r
555 if LibraryPath == None or LibraryPath == "":
\r
556 EdkLogger.warn(None, "Library instance for library class %s is not found" % LibraryClassName)
\r
559 LibraryModule = ModuleDatabase[LibraryPath]
\r
560 if LibraryClassName not in LibraryInstance:
\r
561 LibraryConsumerList.append(LibraryModule)
\r
562 LibraryInstance[LibraryClassName] = LibraryModule
\r
563 EdkLogger.verbose("\t" + LibraryClassName + " : " + str(LibraryModule))
\r
565 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:
\r
566 Constructor.append(LibraryModule)
\r
568 if LibraryModule not in ConsumedByList:
\r
569 ConsumedByList[LibraryModule] = []
\r
570 if module != Module:
\r
571 if module in ConsumedByList[LibraryModule]:
\r
573 ConsumedByList[LibraryModule].append(module)
\r
575 # Initialize the sorted output list to the empty set
\r
577 SortedLibraryList = []
\r
579 # Q <- Set of all nodes with no incoming edges
\r
581 LibraryList = LibraryInstance.values()
\r
583 for m in LibraryList:
\r
585 # check if there're duplicate library classes
\r
587 for Lc in m.LibraryClass:
\r
588 if Lc.LibraryClass in LibraryInstance and str(m) != str(LibraryInstance[Lc.LibraryClass]):
\r
589 EdkLogger.error("AutoGen", AUTOGEN_ERROR,
\r
590 "More than one library instance found for library class %s in module %s" % (Lc.LibraryClass, Module),
\r
591 ExtraData="\t%s\n\t%s" % (LibraryInstance[Lc.LibraryClass], str(m))
\r
593 if ConsumedByList[m] == []:
\r
596 # while Q is not empty do
\r
600 # remove node n from Q
\r
606 SortedLibraryList.append(n)
\r
608 # for each node m with an edge e from n to m do
\r
610 for m in LibraryList:
\r
611 if n not in ConsumedByList[m]:
\r
614 # remove edge e from the graph
\r
616 ConsumedByList[m].remove(n)
\r
618 # If m has no other incoming edges then
\r
620 if ConsumedByList[m] == []:
\r
627 while Q == [] and EdgeRemoved:
\r
628 EdgeRemoved = False
\r
630 # for each node m with a Constructor
\r
632 for m in LibraryList:
\r
633 if m in Constructor:
\r
635 # for each node n without a constructor with an edge e from m to n
\r
637 for n in ConsumedByList[m]:
\r
638 if n not in Constructor:
\r
640 # remove edge e from the graph
\r
642 ConsumedByList[m].remove(n)
\r
644 if ConsumedByList[m] == []:
\r
654 # if any remaining node m in the graph has a constructor and an incoming edge, then the graph has a cycle
\r
656 for m in LibraryList:
\r
657 if ConsumedByList[m] != [] and m in Constructor and len(Constructor) > 1:
\r
658 ErrorMessage = 'Library [%s] with constructors has a cycle' % str(m)
\r
659 EdkLogger.error("AutoGen", AUTOGEN_ERROR, ErrorMessage,
\r
660 "\tconsumed by " + "\n\tconsumed by ".join([str(l) for l in ConsumedByList[m]]))
\r
661 if m not in SortedLibraryList:
\r
662 SortedLibraryList.append(m)
\r
665 # Build the list of constructor and destructir names
\r
666 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
\r
668 SortedLibraryList.reverse()
\r
669 Module.LibraryClasses = sdict()
\r
670 for L in SortedLibraryList:
\r
671 for Lc in L.LibraryClass:
\r
672 Module.LibraryClasses[Lc.LibraryClass, ModuleType] = str(L)
\r
674 # Merge PCDs from library instance
\r
677 if Key not in Module.Pcds:
\r
678 Module.Pcds[Key] = L.Pcds[Key]
\r
680 # Merge GUIDs from library instance
\r
682 for CName in L.Guids:
\r
683 if CName not in Module.Guids:
\r
684 Module.Guids.append(CName)
\r
686 # Merge Protocols from library instance
\r
688 for CName in L.Protocols:
\r
689 if CName not in Module.Protocols:
\r
690 Module.Protocols.append(CName)
\r
692 # Merge Ppis from library instance
\r
694 for CName in L.Ppis:
\r
695 if CName not in Module.Ppis:
\r
696 Module.Ppis.append(CName)
\r
699 # Generate build database for all arches
\r
701 def GenBuildDatabase(self, PcdsSet = {}, InfList = []):
\r
702 for InfFile in InfList:
\r
703 self.AddToInfDatabase(InfFile)
\r
704 self.GenPlatformDatabase()
\r
705 self.GenPackageDatabase()
\r
706 self.GenModuleDatabase(PcdsSet, InfList)
\r
707 self.UpdateLibrariesOfPlatform(InfList)
\r
710 # Return a full path with workspace dir
\r
712 def WorkspaceFile(self, Filename):
\r
713 return WorkspaceFile(self.WorkspaceDir, Filename)
\r
716 # If a module of a platform has its own override libraryclass but the libraryclass not defined in the module
\r
717 # Add this libraryclass to the module
\r
719 def UpdateLibraryClassOfModule(self, InfFileName, LibraryClass, Arch, InstanceFilePath):
\r
721 # Update the library instance itself to add this libraryclass name
\r
723 LibList = self.InfDatabase[NormPath(InstanceFilePath)].Module.Header.LibraryClass
\r
725 for Lib in LibList:
\r
727 # Find this LibraryClass
\r
729 if Lib.LibraryClass == LibraryClass:
\r
733 NewLib = LibraryClassClass()
\r
734 NewLib.LibraryClass = LibraryClass
\r
735 NewLib.SupModuleList = self.InfDatabase[NormPath(InstanceFilePath)].Module.Header.ModuleType.split()
\r
736 self.InfDatabase[NormPath(InstanceFilePath)].Module.Header.LibraryClass.append(NewLib)
\r
739 # Add it to LibraryClasses Section for the module which is using the library
\r
741 LibList = self.InfDatabase[NormPath(InfFileName)].Module.LibraryClasses
\r
743 for Lib in LibList:
\r
745 # Find this LibraryClass
\r
747 if Lib.LibraryClass == LibraryClass:
\r
748 if Arch in Lib.SupArchList:
\r
751 Lib.SupArchList.append(Arch)
\r
754 Lib = LibraryClassClass()
\r
755 Lib.LibraryClass = LibraryClass
\r
756 Lib.SupArchList = [Arch]
\r
757 self.InfDatabase[NormPath(InfFileName)].Module.LibraryClasses.append(Lib)
\r
760 # Create a Inf instance for input inf file and add it to InfDatabase
\r
762 def AddToInfDatabase(self, InfFileName):
\r
763 InfFileName = NormPath(InfFileName)
\r
764 File = self.WorkspaceFile(InfFileName)
\r
765 if os.path.exists(File) and os.path.isfile(File):
\r
766 if InfFileName not in self.InfDatabase:
\r
767 self.InfDatabase[InfFileName] = Inf(File, True, True, self.WorkspaceDir)
\r
769 EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData=File)
\r
772 # Create a Dec instance for input dec file and add it to DecDatabase
\r
774 def AddToDecDatabase(self, DecFileName):
\r
775 DecFileName = NormPath(DecFileName)
\r
776 File = self.WorkspaceFile(DecFileName)
\r
777 if os.path.exists(File) and os.path.isfile(File):
\r
778 if DecFileName not in self.DecDatabase:
\r
779 self.DecDatabase[DecFileName] = Dec(File, True, True, self.WorkspaceDir)
\r
781 EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData=File)
\r
784 # Search PlatformBuildDatabase to find LibraryClass Instance for Module
\r
785 # Return the instance if found
\r
787 def FindLibraryClassInstanceOfModule(self, Lib, Arch, ModuleType, ModuleName):
\r
789 # First find if exist in <LibraryClass> of <Components> from dsc file
\r
791 for Dsc in self.DscDatabase.keys():
\r
792 Platform = self.DscDatabase[Dsc].Platform
\r
793 for Module in Platform.Modules.ModuleList:
\r
794 if Arch in Module.SupArchList:
\r
795 if NormPath(Module.FilePath) == ModuleName:
\r
796 for LibraryClass in Module.LibraryClasses.LibraryList:
\r
797 if LibraryClass.Name == Lib:
\r
798 return NormPath(LibraryClass.FilePath)
\r
800 #Second find if exist in <LibraryClass> of <LibraryClasses> from dsc file
\r
802 return self.FindLibraryClassInstanceOfLibrary(Lib, Arch, ModuleType)
\r
805 # Search PlatformBuildDatabase to find LibraryClass Instance for Library
\r
806 # Return the instance if found
\r
808 def FindLibraryClassInstanceOfLibrary(self, Lib, Arch, Type):
\r
809 for Dsc in self.DscDatabase.keys():
\r
810 Platform = self.DscDatabase[Dsc].Platform
\r
811 if (Lib, Type) in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses:
\r
812 return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, Type)]
\r
813 elif (Lib, '') in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses:
\r
814 return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, '')]
\r
818 # Search DscDatabase to find component definition of ModuleName
\r
819 # Override BuildOption if it is defined in component
\r
821 def FindBuildOptions(self, Arch, ModuleName, BuildOptions):
\r
822 for Dsc in self.DscDatabase.keys():
\r
824 # First find if exist in <BuildOptions> of <Components> from dsc file
\r
825 # if find, use that override the one defined in inf file
\r
827 Platform = self.DscDatabase[Dsc].Platform
\r
828 for Module in Platform.Modules.ModuleList:
\r
829 if Arch in Module.SupArchList:
\r
830 if NormPath(Module.FilePath) == ModuleName:
\r
831 for BuildOption in Module.ModuleSaBuildOption.BuildOptionList:
\r
832 BuildOptions[(BuildOption.ToolChainFamily, BuildOption.ToolChain)] = BuildOption.Option
\r
835 # Search platform database, package database, module database and PcdsSet from Fdf
\r
838 def FindPcd(self, Arch, ModuleName, Name, Guid, Type, PcdsSet):
\r
844 IsOverrided = False
\r
845 IsFoundInDsc = False
\r
846 IsFoundInDec = False
\r
848 # First get information from platform database
\r
850 for Dsc in self.Build[Arch].PlatformDatabase.keys():
\r
851 Pcds = self.Build[Arch].PlatformDatabase[Dsc].Pcds
\r
852 if (Name, Guid) in Pcds:
\r
853 Type = Pcds[(Name, Guid)].Type
\r
854 DatumType = Pcds[(Name, Guid)].DatumType
\r
855 Value = Pcds[(Name, Guid)].DefaultValue
\r
856 Token = Pcds[(Name, Guid)].TokenValue
\r
857 MaxDatumSize = Pcds[(Name, Guid)].MaxDatumSize
\r
858 SkuInfoList = Pcds[(Name, Guid)].SkuInfoList
\r
860 IsFoundInDsc = True
\r
864 # Second get information from package database
\r
866 for Dec in self.Build[Arch].PackageDatabase.keys():
\r
867 Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds
\r
868 if (Name, Guid) in Pcds:
\r
869 DatumType = Pcds[(Name, Guid)].DatumType
\r
870 Token = Pcds[(Name, Guid)].TokenValue
\r
872 IsFoundInDec = True
\r
874 if not IsFoundInDec:
\r
875 ErrorMsg = "Pcd '%s.%s' defined in module '%s' is not found in any package" % (Guid, Name, ModuleName)
\r
876 EdkLogger.error("AutoGen", PARSER_ERROR, ErrorMsg)
\r
879 # Third get information from <Pcd> of <Compontents> from module database
\r
881 for Dsc in self.DscDatabase.keys():
\r
882 for Module in self.DscDatabase[Dsc].Platform.Modules.ModuleList:
\r
883 if Arch in Module.SupArchList:
\r
884 if NormPath(Module.FilePath) == ModuleName:
\r
885 for Pcd in Module.PcdBuildDefinitions:
\r
886 if (Name, Guid) == (Pcd.CName, Pcd.TokenSpaceGuidCName):
\r
887 if Pcd.DefaultValue != '':
\r
888 Value = Pcd.DefaultValue
\r
889 if Pcd.MaxDatumSize != '':
\r
890 MaxDatumSize = Pcd.MaxDatumSize
\r
891 IsFoundInDsc = True
\r
896 # Last get information from PcdsSet defined by FDF
\r
898 if (Name, Guid) in PcdsSet:
\r
899 Value = PcdsSet[(Name, Guid)]
\r
900 IsFoundInDsc = True
\r
904 # Not found in any platform and fdf
\r
906 if not IsFoundInDsc:
\r
907 ErrorMsg = "Pcd '%s.%s' defined in module '%s' is not found in any platform for %s" % (Guid, Name, ModuleName, Arch)
\r
908 EdkLogger.error("AutoGen", PARSER_ERROR, ErrorMsg)
\r
910 return PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided)
\r
913 # Search in InfDatabase, find the supmodulelist of the libraryclass
\r
915 def FindSupModuleListOfLibraryClass(self, LibraryClass, OverridedLibraryClassList):
\r
916 Name = LibraryClass.Name
\r
917 FilePath = NormPath(LibraryClass.FilePath)
\r
918 SupModuleList = copy.copy(LibraryClass.SupModuleList)
\r
921 # If the SupModuleList means all, remove overrided module types of platform
\r
923 if SupModuleList == DataType.SUP_MODULE_LIST:
\r
924 EdkLogger.debug(EdkLogger.DEBUG_3, "\tLibraryClass %s supports all module types" % Name)
\r
925 for Item in OverridedLibraryClassList:
\r
927 # Find a library class with the same name
\r
929 if Item.Name == Name:
\r
931 # Do nothing if it is itself
\r
933 if Item.SupModuleList == DataType.SUP_MODULE_LIST:
\r
936 # If not itself, check arch first
\r
938 for Arch in LibraryClass.SupArchList:
\r
940 # If arch is supportted, remove all related module type
\r
942 if Arch in Item.SupArchList:
\r
943 for ModuleType in Item.SupModuleList:
\r
944 EdkLogger.debug(EdkLogger.DEBUG_3, "\tLibraryClass %s has specific defined module types" % Name)
\r
945 if ModuleType in SupModuleList:
\r
946 SupModuleList.remove(ModuleType)
\r
948 return SupModuleList
\r
951 # Check if the module is defined in <Compentent> of <Platform>
\r
953 def IsModuleDefinedInPlatform(self, Inf, Arch, InfList):
\r
954 # for InfFile in InfList:
\r
955 # if Inf == NormPath(InfFile):
\r
957 Inf = NormPath(Inf)
\r
958 for Dsc in self.DscDatabase.values():
\r
959 for LibraryClass in Dsc.Platform.LibraryClasses.LibraryList:
\r
960 if Inf == NormPath(LibraryClass.FilePath) and Arch in LibraryClass.SupArchList:
\r
962 for Module in Dsc.Platform.Modules.ModuleList:
\r
963 if Inf == NormPath(Module.FilePath) and Arch in Module.SupArchList:
\r
965 for Item in Module.LibraryClasses.LibraryList:
\r
966 if Inf == NormPath(Item.FilePath):
\r
972 # Show all content of the workspacebuild
\r
974 def ShowWorkspaceBuild(self):
\r
975 print ewb.DscDatabase
\r
976 print ewb.InfDatabase
\r
977 print ewb.DecDatabase
\r
978 print 'SupArchList', ewb.SupArchList
\r
979 print 'BuildTarget', ewb.BuildTarget
\r
980 print 'SkuId', ewb.SkuId
\r
982 for arch in ewb.SupArchList:
\r
985 for platform in ewb.Build[arch].PlatformDatabase.keys():
\r
986 p = ewb.Build[arch].PlatformDatabase[platform]
\r
987 print 'DescFilePath = ', p.DescFilePath
\r
988 print 'PlatformName = ', p.PlatformName
\r
989 print 'Guid = ', p.Guid
\r
990 print 'Version = ', p.Version
\r
991 print 'OutputDirectory = ', p.OutputDirectory
\r
992 print 'FlashDefinition = ', p.FlashDefinition
\r
993 print 'SkuIds = ', p.SkuIds
\r
994 print 'Modules = ', p.Modules
\r
995 print 'LibraryClasses = ', p.LibraryClasses
\r
996 print 'Pcds = ', p.Pcds
\r
997 for item in p.Pcds.keys():
\r
999 print 'BuildOptions = ', p.BuildOptions
\r
1004 for package in ewb.Build[arch].PackageDatabase.keys():
\r
1005 p = ewb.Build[arch].PackageDatabase[package]
\r
1006 print 'DescFilePath = ', p.DescFilePath
\r
1007 print 'PackageName = ', p.PackageName
\r
1008 print 'Guid = ', p.Guid
\r
1009 print 'Version = ', p.Version
\r
1010 print 'Protocols = ', p.Protocols
\r
1011 print 'Ppis = ', p.Ppis
\r
1012 print 'Guids = ', p.Guids
\r
1013 print 'Includes = ', p.Includes
\r
1014 print 'LibraryClasses = ', p.LibraryClasses
\r
1015 print 'Pcds = ', p.Pcds
\r
1016 for item in p.Pcds.keys():
\r
1017 print p.Pcds[item]
\r
1022 for module in ewb.Build[arch].ModuleDatabase.keys():
\r
1023 p = ewb.Build[arch].ModuleDatabase[module]
\r
1024 print 'DescFilePath = ', p.DescFilePath
\r
1025 print 'BaseName = ', p.BaseName
\r
1026 print 'ModuleType = ', p.ModuleType
\r
1027 print 'Guid = ', p.Guid
\r
1028 print 'Version = ', p.Version
\r
1029 print 'CustomMakefile = ', p.CustomMakefile
\r
1030 print 'Specification = ', p.Specification
\r
1031 print 'PcdIsDriver = ', p.PcdIsDriver
\r
1032 for Lib in p.LibraryClass:
\r
1033 print 'LibraryClassDefinition = ', Lib.LibraryClass, 'SupModList = ', Lib.SupModList
\r
1034 print 'ModuleEntryPointList = ', p.ModuleEntryPointList
\r
1035 print 'ModuleUnloadImageList = ', p.ModuleUnloadImageList
\r
1036 print 'ConstructorList = ', p.ConstructorList
\r
1037 print 'DestructorList = ', p.DestructorList
\r
1039 print 'Binaries = '
\r
1040 for item in p.Binaries:
\r
1041 print item.BinaryFile, item.FeatureFlag
\r
1042 print 'Sources = '
\r
1043 for item in p.Sources:
\r
1044 print item.SourceFile
\r
1045 print 'LibraryClasses = ', p.LibraryClasses
\r
1046 print 'Protocols = ', p.Protocols
\r
1047 print 'Ppis = ', p.Ppis
\r
1048 print 'Guids = ', p.Guids
\r
1049 print 'Includes = ', p.Includes
\r
1050 print 'Packages = ', p.Packages
\r
1051 print 'Pcds = ', p.Pcds
\r
1052 for item in p.Pcds.keys():
\r
1053 print p.Pcds[item]
\r
1054 print 'BuildOptions = ', p.BuildOptions
\r
1055 print 'Depex = ', p.Depex
\r
1060 # This acts like the main() function for the script, unless it is 'import'ed into another
\r
1063 if __name__ == '__main__':
\r
1064 # Nothing to do here. Could do some unit tests.
\r
1065 w = os.getenv('WORKSPACE')
\r
1066 ewb = WorkspaceBuild('Nt32Pkg/Nt32Pkg.dsc', w)
\r
1067 ewb.GenBuildDatabase({('PcdDevicePathSupportDevicePathFromText, gEfiMdeModulePkgTokenSpaceGuid') : 'KKKKKKKKKKKKKKKKKKKKK'}, ['Test.Inf'])
\r
1068 ewb.ShowWorkspaceBuild()
\r