From 30fdf1140b8d1ce93f3821d986fa165552023440 Mon Sep 17 00:00:00 2001 From: lgao4 Date: Fri, 17 Jul 2009 09:10:31 +0000 Subject: Check In tool source code based on Build tool project revision r1655. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8964 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Source/Python/Common/EdkIIWorkspaceBuild.py | 1669 ++++++++++++++++++++ 1 file changed, 1669 insertions(+) create mode 100644 BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py (limited to 'BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py') diff --git a/BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py b/BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py new file mode 100644 index 0000000000..82ab1796ad --- /dev/null +++ b/BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py @@ -0,0 +1,1669 @@ +## @file +# This file is used to define each component of the build database +# +# Copyright (c) 2007 ~ 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +## +# Import Modules +# +import os, string, copy, pdb, copy +import EdkLogger +import DataType +from InfClassObject import * +from DecClassObject import * +from DscClassObject import * +from String import * +from BuildToolError import * +from Misc import sdict +import Database as Database +import time as time + +## PcdClassObject +# +# This Class is used for PcdObject +# +# @param object: Inherited from object class +# @param Name: Input value for Name of Pcd, default is None +# @param Guid: Input value for Guid of Pcd, default is None +# @param Type: Input value for Type of Pcd, default is None +# @param DatumType: Input value for DatumType of Pcd, default is None +# @param Value: Input value for Value of Pcd, default is None +# @param Token: Input value for Token of Pcd, default is None +# @param MaxDatumSize: Input value for MaxDatumSize of Pcd, default is None +# @param SkuInfoList: Input value for SkuInfoList of Pcd, default is {} +# @param IsOverrided: Input value for IsOverrided of Pcd, default is False +# +# @var TokenCName: To store value for TokenCName +# @var TokenSpaceGuidCName: To store value for TokenSpaceGuidCName +# @var Type: To store value for Type +# @var DatumType: To store value for DatumType +# @var TokenValue: To store value for TokenValue +# @var MaxDatumSize: To store value for MaxDatumSize +# @var SkuInfoList: To store value for SkuInfoList +# @var IsOverrided: To store value for IsOverrided +# @var Phase: To store value for Phase, default is "DXE" +# +class PcdClassObject(object): + def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, IsOverrided = False): + self.TokenCName = Name + self.TokenSpaceGuidCName = Guid + self.Type = Type + self.DatumType = DatumType + self.DefaultValue = Value + self.TokenValue = Token + self.MaxDatumSize = MaxDatumSize + self.SkuInfoList = SkuInfoList + self.IsOverrided = IsOverrided + self.Phase = "DXE" + + ## Convert the class to a string + # + # Convert each member of the class to string + # Organize to a signle line format string + # + # @retval Rtn Formatted String + # + def __str__(self): + Rtn = '\tTokenCName=' + str(self.TokenCName) + ', ' + \ + 'TokenSpaceGuidCName=' + str(self.TokenSpaceGuidCName) + ', ' + \ + 'Type=' + str(self.Type) + ', ' + \ + 'DatumType=' + str(self.DatumType) + ', ' + \ + 'DefaultValue=' + str(self.DefaultValue) + ', ' + \ + 'TokenValue=' + str(self.TokenValue) + ', ' + \ + 'MaxDatumSize=' + str(self.MaxDatumSize) + ', ' + for Item in self.SkuInfoList.values(): + Rtn = Rtn + 'SkuId=' + Item.SkuId + ', ' + 'SkuIdName=' + Item.SkuIdName + Rtn = Rtn + str(self.IsOverrided) + + return Rtn + + ## Override __eq__ function + # + # Check whether pcds are the same + # + # @retval False The two pcds are different + # @retval True The two pcds are the same + # + def __eq__(self, Other): + return Other != None and self.TokenCName == Other.TokenCName and self.TokenSpaceGuidCName == Other.TokenSpaceGuidCName + + ## Override __hash__ function + # + # Use (TokenCName, TokenSpaceGuidCName) as key in hash table + # + # @retval truple() Key for hash table + # + def __hash__(self): + return hash((self.TokenCName, self.TokenSpaceGuidCName)) + +## LibraryClassObject +# +# This Class defines LibraryClassObject used in BuildDatabase +# +# @param object: Inherited from object class +# @param Name: Input value for LibraryClassName, default is None +# @param SupModList: Input value for SupModList, default is [] +# @param Type: Input value for Type, default is None +# +# @var LibraryClass: To store value for LibraryClass +# @var SupModList: To store value for SupModList +# @var Type: To store value for Type +# +class LibraryClassObject(object): + def __init__(self, Name = None, SupModList = [], Type = None): + self.LibraryClass = Name + self.SupModList = SupModList + if Type != None: + self.SupModList = CleanString(Type).split(DataType.TAB_SPACE_SPLIT) + +## ModuleBuildClassObject +# +# This Class defines ModuleBuildClass +# +# @param object: Inherited from object class +# +# @var DescFilePath: To store value for DescFilePath +# @var BaseName: To store value for BaseName +# @var ModuleType: To store value for ModuleType +# @var Guid: To store value for Guid +# @var Version: To store value for Version +# @var PcdIsDriver: To store value for PcdIsDriver +# @var BinaryModule: To store value for BinaryModule +# @var CustomMakefile: To store value for CustomMakefile +# @var Specification: To store value for Specification +# @var Shadow To store value for Shadow +# @var LibraryClass: To store value for LibraryClass, it is a list structure as +# [ LibraryClassObject, ...] +# @var ModuleEntryPointList: To store value for ModuleEntryPointList +# @var ModuleUnloadImageList: To store value for ModuleUnloadImageList +# @var ConstructorList: To store value for ConstructorList +# @var DestructorList: To store value for DestructorList +# @var Binaries: To store value for Binaries, it is a list structure as +# [ ModuleBinaryClassObject, ...] +# @var Sources: To store value for Sources, it is a list structure as +# [ ModuleSourceFilesClassObject, ... ] +# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as +# { [LibraryClassName, ModuleType] : LibraryClassInfFile } +# @var Protocols: To store value for Protocols, it is a list structure as +# [ ProtocolName, ... ] +# @var Ppis: To store value for Ppis, it is a list structure as +# [ PpiName, ... ] +# @var Guids: To store value for Guids, it is a list structure as +# [ GuidName, ... ] +# @var Includes: To store value for Includes, it is a list structure as +# [ IncludePath, ... ] +# @var Packages: To store value for Packages, it is a list structure as +# [ DecFileName, ... ] +# @var Pcds: To store value for Pcds, it is a set structure as +# { [(PcdCName, PcdGuidCName)] : PcdClassObject} +# @var BuildOptions: To store value for BuildOptions, it is a set structure as +# { [BuildOptionKey] : BuildOptionValue} +# @var Depex: To store value for Depex +# +class ModuleBuildClassObject(object): + def __init__(self): + self.AutoGenVersion = 0 + self.DescFilePath = '' + self.BaseName = '' + self.ModuleType = '' + self.Guid = '' + self.Version = '' + self.PcdIsDriver = '' + self.BinaryModule = '' + self.Shadow = '' + self.CustomMakefile = {} + self.Specification = {} + self.LibraryClass = [] + self.ModuleEntryPointList = [] + self.ModuleUnloadImageList = [] + self.ConstructorList = [] + self.DestructorList = [] + + self.Binaries = [] + self.Sources = [] + self.LibraryClasses = sdict() + self.Libraries = [] + self.Protocols = [] + self.Ppis = [] + self.Guids = [] + self.Includes = [] + self.Packages = [] + self.Pcds = {} + self.BuildOptions = {} + self.Depex = '' + + ## Convert the class to a string + # + # Convert member DescFilePath of the class to a string + # + # @retval string Formatted String + # + def __str__(self): + return self.DescFilePath + + ## Override __eq__ function + # + # Check whether ModuleBuildClassObjects are the same + # + # @retval False The two ModuleBuildClassObjects are different + # @retval True The two ModuleBuildClassObjects are the same + # + def __eq__(self, Other): + return self.DescFilePath == str(Other) + + ## Override __hash__ function + # + # Use DescFilePath as key in hash table + # + # @retval string Key for hash table + # + def __hash__(self): + return hash(self.DescFilePath) + +## PackageBuildClassObject +# +# This Class defines PackageBuildClass +# +# @param object: Inherited from object class +# +# @var DescFilePath: To store value for DescFilePath +# @var PackageName: To store value for PackageName +# @var Guid: To store value for Guid +# @var Version: To store value for Version +# @var Protocols: To store value for Protocols, it is a set structure as +# { [ProtocolName] : Protocol Guid, ... } +# @var Ppis: To store value for Ppis, it is a set structure as +# { [PpiName] : Ppi Guid, ... } +# @var Guids: To store value for Guids, it is a set structure as +# { [GuidName] : Guid, ... } +# @var Includes: To store value for Includes, it is a list structure as +# [ IncludePath, ... ] +# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as +# { [LibraryClassName] : LibraryClassInfFile } +# @var Pcds: To store value for Pcds, it is a set structure as +# { [(PcdCName, PcdGuidCName)] : PcdClassObject} +# +class PackageBuildClassObject(object): + def __init__(self): + self.DescFilePath = '' + self.PackageName = '' + self.Guid = '' + self.Version = '' + + self.Protocols = {} + self.Ppis = {} + self.Guids = {} + self.Includes = [] + self.LibraryClasses = {} + self.Pcds = {} + + ## Convert the class to a string + # + # Convert member DescFilePath of the class to a string + # + # @retval string Formatted String + # + def __str__(self): + return self.DescFilePath + + ## Override __eq__ function + # + # Check whether PackageBuildClassObjects are the same + # + # @retval False The two PackageBuildClassObjects are different + # @retval True The two PackageBuildClassObjects are the same + # + def __eq__(self, Other): + return self.DescFilePath == str(Other) + + ## Override __hash__ function + # + # Use DescFilePath as key in hash table + # + # @retval string Key for hash table + # + def __hash__(self): + return hash(self.DescFilePath) + +## PlatformBuildClassObject +# +# This Class defines PlatformBuildClass +# +# @param object: Inherited from object class +# +# @var DescFilePath: To store value for DescFilePath +# @var PlatformName: To store value for PlatformName +# @var Guid: To store value for Guid +# @var Version: To store value for Version +# @var DscSpecification: To store value for DscSpecification +# @var OutputDirectory: To store value for OutputDirectory +# @var FlashDefinition: To store value for FlashDefinition +# @var BuildNumber: To store value for BuildNumber +# @var MakefileName: To store value for MakefileName +# @var SkuIds: To store value for SkuIds, it is a set structure as +# { 'SkuName' : SkuId, '!include' : includefilename, ...} +# @var Modules: To store value for Modules, it is a list structure as +# [ InfFileName, ... ] +# @var Libraries: To store value for Libraries, it is a list structure as +# [ InfFileName, ... ] +# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as +# { (LibraryClassName, ModuleType) : LibraryClassInfFile } +# @var Pcds: To store value for Pcds, it is a set structure as +# { [(PcdCName, PcdGuidCName)] : PcdClassObject } +# @var BuildOptions: To store value for BuildOptions, it is a set structure as +# { [BuildOptionKey] : BuildOptionValue } +# +class PlatformBuildClassObject(object): + def __init__(self): + self.DescFilePath = '' + self.PlatformName = '' + self.Guid = '' + self.Version = '' + self.DscSpecification = '' + self.OutputDirectory = '' + self.FlashDefinition = '' + self.BuildNumber = '' + self.MakefileName = '' + + self.SkuIds = {} + self.Modules = [] + self.LibraryInstances = [] + self.LibraryClasses = {} + self.Libraries = {} + self.Pcds = {} + self.BuildOptions = {} + + ## Convert the class to a string + # + # Convert member DescFilePath of the class to a string + # + # @retval string Formatted String + # + def __str__(self): + return self.DescFilePath + + ## Override __eq__ function + # + # Check whether PlatformBuildClassObjects are the same + # + # @retval False The two PlatformBuildClassObjects are different + # @retval True The two PlatformBuildClassObjects are the same + # + def __eq__(self, other): + return self.DescFilePath == str(other) + + ## Override __hash__ function + # + # Use DescFilePath as key in hash table + # + # @retval string Key for hash table + # + def __hash__(self): + return hash(self.DescFilePath) + +## ItemBuild +# +# This Class defines Module/Platform/Package databases for build system +# +# @param object: Inherited from object class +# @param Arch: Build arch +# @param Platform: Build Platform +# @param Package: Build Package +# @param Module: Build Module +# +# @var Arch: To store value for Build Arch +# @var PlatformDatabase: To store value for PlatformDatabase, it is a set structure as +# { [DscFileName] : PlatformBuildClassObject, ...} +# @var PackageDatabase: To store value for PackageDatabase, it is a set structure as +# { [DecFileName] : PacakgeBuildClassObject, ...} +# @var ModuleDatabase: To store value for ModuleDatabase, it is a list structure as +# { [InfFileName] : ModuleBuildClassObject, ...} +# +class ItemBuild(object): + def __init__(self, Arch, Platform = None, Package = None, Module = None): + self.Arch = Arch + self.PlatformDatabase = {} + self.PackageDatabase = {} + self.ModuleDatabase = {} + +## WorkspaceBuild +# +# This class is used to parse active platform to init all inf/dec/dsc files +# Generate module/package/platform databases for build +# +# @param object: Inherited from object class +# @param ActivePlatform: Input value for current active platform +# @param WorkspaceDir: Input value for current WorkspaceDir +# +# @var WorkspaceDir: To store value for WorkspaceDir +# @var SupArchList: To store value for SupArchList, selection scope is in below list +# EBC | IA32 | X64 | IPF | ARM | PPC +# @var BuildTarget: To store value for WorkspaceDir, selection scope is in below list +# RELEASE | DEBUG +# @var SkuId: To store value for SkuId +# @var Fdf: To store value for Fdf +# @var FdTargetList: To store value for FdTargetList +# @var FvTargetList: To store value for FvTargetList +# @var TargetTxt: To store value for TargetTxt, it is a set structure as +# TargetTxtClassObject +# @var ToolDef: To store value for ToolDef, it is a set structure as +# ToolDefClassObject +# @var InfDatabase: To store value for InfDatabase, it is a set structure as +# { [InfFileName] : InfClassObject} +# @var DecDatabase: To store value for DecDatabase, it is a set structure as +# { [DecFileName] : DecClassObject} +# @var DscDatabase: To store value for DscDatabase, it is a set structure as +# { [DscFileName] : DscClassObject} +# @var Build: To store value for DscDatabase, it is a set structure as +# ItemBuild +# @var DscFileName: To store value for Active Platform +# @var UnFoundPcdInDsc: To store values for the pcds defined in INF/DEC but not found in DSC, it is a set structure as +# { (PcdGuid, PcdCName, Arch) : DecFileName } +# +class WorkspaceBuild(object): + def __init__(self, ActivePlatform, WorkspaceDir): + self.WorkspaceDir = NormPath(WorkspaceDir) + self.SupArchList = [] + self.BuildTarget = [] + self.SkuId = '' + self.Fdf = '' + self.FdTargetList = [] + self.FvTargetList = [] + self.TargetTxt = None + self.ToolDef = None + + self.InfDatabase = {} + self.DecDatabase = {} + self.DscDatabase = {} + + self.UnFoundPcdInDsc = {} + + # + # Init build for all arches + # + self.Build = {} + for Arch in DataType.ARCH_LIST: + self.Build[Arch] = ItemBuild(Arch) + + # + # Init build database + # + self.Db = Database.Database(DATABASE_PATH) + self.Db.InitDatabase() + + # + # Get active platform + # + self.DscFileName = NormPath(ActivePlatform) + File = self.WorkspaceFile(self.DscFileName) + if os.path.exists(File) and os.path.isfile(File): + self.DscDatabase[self.DscFileName] = Dsc(File, False, True, self.WorkspaceDir, self.Db) + else: + EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData = File) + + # + # Parse platform to get module + # + for DscFile in self.DscDatabase.keys(): + Platform = self.DscDatabase[DscFile].Platform + + # + # Get global information + # + Tmp = set() + for Arch in DataType.ARCH_LIST: + for Item in Platform.Header[Arch].SupArchList: + Tmp.add(Item) + self.SupArchList = list(Tmp) + Tmp = set() + for Arch in DataType.ARCH_LIST: + for Item in Platform.Header[Arch].BuildTargets: + Tmp.add(Item) + self.BuildTarget = list(Tmp) + for Arch in self.SupArchList: + self.SkuId = Platform.Header[Arch].SkuIdName + self.Fdf = Platform.FlashDefinitionFile.FilePath + + # + # Get all inf files + # + for Item in Platform.LibraryClasses.LibraryList: + for Arch in Item.SupArchList: + self.AddToInfDatabase(Item.FilePath) + + for Item in Platform.Libraries.LibraryList: + for Arch in Item.SupArchList: + self.AddToInfDatabase(Item.FilePath) + + for Item in Platform.Modules.ModuleList: + for Arch in Item.SupArchList: + # + # Add modules + # + Module = Item.FilePath + self.AddToInfDatabase(Module) + # + # Add library used in modules + # + for Lib in Item.LibraryClasses.LibraryList: + self.AddToInfDatabase(Lib.FilePath) + self.UpdateLibraryClassOfModule(Module, Lib.Name, Arch, Lib.FilePath) + + # + # Parse module to get package + # + for InfFile in self.InfDatabase.keys(): + Module = self.InfDatabase[InfFile].Module + # + # Get all dec + # + for Item in Module.PackageDependencies: + for Arch in Item.SupArchList: + self.AddToDecDatabase(Item.FilePath) + # End of self.Init() + + ## Generate PlatformDatabase + # + # Go through each arch to get all items in DscDatabase to PlatformDatabase + # + def GenPlatformDatabase(self, PcdsSet={}): + for Dsc in self.DscDatabase.keys(): + Platform = self.DscDatabase[Dsc].Platform + for Arch in self.SupArchList: + Pb = PlatformBuildClassObject() + + # + # Defines + # + Pb.DescFilePath = Dsc + Pb.PlatformName = Platform.Header[Arch].Name + if Pb.PlatformName == '': + EdkLogger.error("AutoGen", PARSER_ERROR, "The BaseName of platform %s is not defined for arch %s" % (Dsc, Arch)) + Pb.Guid = Platform.Header[Arch].Guid + Pb.Version = Platform.Header[Arch].Version + Pb.DscSpecification = Platform.Header[Arch].DscSpecification + Pb.OutputDirectory = Platform.Header[Arch].OutputDirectory + Pb.FlashDefinition = Platform.FlashDefinitionFile.FilePath + Pb.BuildNumber = Platform.Header[Arch].BuildNumber + + # + # SkuId + # + for Key in Platform.SkuInfos.SkuInfoList.keys(): + Pb.SkuIds[Key] = Platform.SkuInfos.SkuInfoList[Key] + + # + # Module + # + for Item in Platform.Modules.ModuleList: + if Arch in Item.SupArchList: + Pb.Modules.append(Item.FilePath) + + # + # BuildOptions + # + for Item in Platform.BuildOptions.BuildOptionList: + if Arch in Item.SupArchList: + Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option + + # + # LibraryClass + # + for Item in Platform.LibraryClasses.LibraryList: + SupModuleList = self.FindSupModuleListOfLibraryClass(Item, Platform.LibraryClasses.LibraryList, Arch) + if Arch in Item.SupArchList: + for ModuleType in SupModuleList: + Pb.LibraryClasses[(Item.Name, ModuleType)] = Item.FilePath + + # + # Libraries + # + for Item in Platform.Libraries.LibraryList: + for ItemArch in Item.SupArchList: + Library = self.InfDatabase[Item.FilePath] + if ItemArch not in Library.Module.Header: + continue + Pb.Libraries[Library.Module.Header[ItemArch].Name] = Item.FilePath + + # + # Pcds + # + for Item in Platform.DynamicPcdBuildDefinitions: + if Arch in Item.SupArchList: + Name = Item.CName + Guid = Item.TokenSpaceGuidCName + Type = Item.ItemType + DatumType = Item.DatumType + Value = Item.DefaultValue + Token = Item.Token + MaxDatumSize = Item.MaxDatumSize + SkuInfoList = Item.SkuInfoList + Pb.Pcds[(Name, Guid)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False) + + for (Name, Guid) in PcdsSet: + Value = PcdsSet[Name, Guid] + for PcdType in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]: + for Dec in self.Build[Arch].PackageDatabase: + Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds + if (Name, Guid, PcdType) in Pcds: + Pcd = Pcds[(Name, Guid, PcdType)] + Type = PcdType + DatumType = Pcd.DatumType + Token = Pcd.TokenValue + MaxDatumSize = Pcd.MaxDatumSize + SkuInfoList = Pcd.SkuInfoList + Pb.Pcds[(Name, Guid)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False) + break + else: + # nothing found + continue + # found in one package, find next PCD + break + else: + EdkLogger.error("AutoGen", PARSER_ERROR, "PCD is not found in any package", ExtraData="%s.%s" % (Guid, Name)) + # + # Add to database + # + self.Build[Arch].PlatformDatabase[Dsc] = Pb + Pb = None + + ## Generate PackageDatabase + # + # Go through each arch to get all items in DecDatabase to PackageDatabase + # + def GenPackageDatabase(self): + for Dec in self.DecDatabase.keys(): + Package = self.DecDatabase[Dec].Package + + for Arch in self.SupArchList: + Pb = PackageBuildClassObject() + + # + # Defines + # + Pb.DescFilePath = Dec + Pb.PackageName = Package.Header[Arch].Name + if Pb.PackageName == '': + EdkLogger.error("AutoGen", PARSER_ERROR, "The BaseName of package %s is not defined for arch %s" % (Dec, Arch)) + + Pb.Guid = Package.Header[Arch].Guid + Pb.Version = Package.Header[Arch].Version + + # + # Protocols + # + for Item in Package.ProtocolDeclarations: + if Arch in Item.SupArchList: + Pb.Protocols[Item.CName] = Item.Guid + + # + # Ppis + # + for Item in Package.PpiDeclarations: + if Arch in Item.SupArchList: + Pb.Ppis[Item.CName] = Item.Guid + + # + # Guids + # + for Item in Package.GuidDeclarations: + if Arch in Item.SupArchList: + Pb.Guids[Item.CName] = Item.Guid + + # + # Includes + # + for Item in Package.Includes: + if Arch in Item.SupArchList: + Pb.Includes.append(Item.FilePath) + + # + # LibraryClasses + # + for Item in Package.LibraryClassDeclarations: + if Arch in Item.SupArchList: + Pb.LibraryClasses[Item.LibraryClass] = Item.RecommendedInstance + + # + # Pcds + # + for Item in Package.PcdDeclarations: + if Arch in Item.SupArchList: + Name = Item.CName + Guid = Item.TokenSpaceGuidCName + Type = Item.ItemType + DatumType = Item.DatumType + Value = Item.DefaultValue + Token = Item.Token + MaxDatumSize = Item.MaxDatumSize + SkuInfoList = Item.SkuInfoList + Pb.Pcds[(Name, Guid, Type)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False) + + # + # Add to database + # + self.Build[Arch].PackageDatabase[Dec] = Pb + Pb = None + + ## Generate ModuleDatabase + # + # Go through each arch to get all items in InfDatabase to ModuleDatabase + # + def GenModuleDatabase(self, InfList = []): + for Inf in self.InfDatabase.keys(): + Module = self.InfDatabase[Inf].Module + + for Arch in self.SupArchList: + if not self.IsModuleDefinedInPlatform(Inf, Arch, InfList) or Arch not in Module.Header: + continue + + ModuleHeader = Module.Header[Arch] + Pb = ModuleBuildClassObject() + + # + # Defines + # + Pb.DescFilePath = Inf + Pb.BaseName = ModuleHeader.Name + if Pb.BaseName == '': + EdkLogger.error("AutoGen", PARSER_ERROR, "The BaseName of module %s is not defined for arch %s" % (Inf, Arch)) + Pb.Guid = ModuleHeader.Guid + Pb.Version = ModuleHeader.Version + Pb.ModuleType = ModuleHeader.ModuleType + Pb.PcdIsDriver = ModuleHeader.PcdIsDriver + Pb.BinaryModule = ModuleHeader.BinaryModule + Pb.CustomMakefile = ModuleHeader.CustomMakefile + Pb.Shadow = ModuleHeader.Shadow + + # + # Specs os Defines + # + Pb.Specification = ModuleHeader.Specification + Pb.Specification[TAB_INF_DEFINES_EDK_RELEASE_VERSION] = ModuleHeader.EdkReleaseVersion + Pb.Specification[TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION] = ModuleHeader.EfiSpecificationVersion + Pb.AutoGenVersion = int(ModuleHeader.InfVersion, 0) + + # + # LibraryClass of Defines + # + for Item in ModuleHeader.LibraryClass: + Pb.LibraryClass.append(LibraryClassObject(Item.LibraryClass, Item.SupModuleList, None)) + + # + # Module image and library of Defines + # + for Item in Module.ExternImages: + if Item.ModuleEntryPoint != '' and Item.ModuleEntryPoint not in Pb.ModuleEntryPointList: + Pb.ModuleEntryPointList.append(Item.ModuleEntryPoint) + if Item.ModuleUnloadImage != '' and Item.ModuleUnloadImage not in Pb.ModuleUnloadImageList: + Pb.ModuleUnloadImageList.append(Item.ModuleUnloadImage) + for Item in Module.ExternLibraries: + if Item.Constructor != '' and Item.Constructor not in Pb.ConstructorList: + Pb.ConstructorList.append(Item.Constructor) + if Item.Destructor != '' and Item.Destructor not in Pb.DestructorList: + Pb.DestructorList.append(Item.Destructor) + + # + # Binaries + # + for Item in Module.Binaries: + if Arch in Item.SupArchList: + FileName = Item.BinaryFile + FileType = Item.FileType + Target = Item.Target + FeatureFlag = Item.FeatureFlag + Pb.Binaries.append(ModuleBinaryFileClass(FileName, FileType, Target, FeatureFlag, Arch.split())) + + # + # Sources + # + for Item in Module.Sources: + if Arch in Item.SupArchList: + SourceFile = Item.SourceFile + TagName = Item.TagName + ToolCode = Item.ToolCode + ToolChainFamily = Item.ToolChainFamily + FeatureFlag = Item.FeatureFlag + Pb.Sources.append(ModuleSourceFileClass(SourceFile, TagName, ToolCode, ToolChainFamily, FeatureFlag)) + + # + # Protocols + # + for Item in Module.Protocols: + if Arch in Item.SupArchList: + Pb.Protocols.append(Item.CName) + + # + # Ppis + # + for Item in Module.Ppis: + if Arch in Item.SupArchList: + Pb.Ppis.append(Item.CName) + + # + # Guids + # + for Item in Module.Guids: + if Arch in Item.SupArchList: + Pb.Ppis.append(Item.CName) + + # + # Includes + # + for Item in Module.Includes: + if Arch in Item.SupArchList: + Pb.Includes.append(Item.FilePath) + + # + # Packages + # + for Item in Module.PackageDependencies: + if Arch in Item.SupArchList: + Pb.Packages.append(Item.FilePath) + + # + # BuildOptions + # + for Item in Module.BuildOptions: + if Arch in Item.SupArchList: + if (Item.ToolChainFamily, Item.ToolChain) not in Pb.BuildOptions: + Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option + else: + OptionString = Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] + Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = OptionString + " " + Item.Option + self.FindBuildOptions(Arch, Inf, Pb.BuildOptions) + + # + # Depex + # + for Item in Module.Depex: + if Arch in Item.SupArchList: + Pb.Depex = Pb.Depex + Item.Depex + ' ' + Pb.Depex = Pb.Depex.strip() + + # + # LibraryClasses + # + for Item in Module.LibraryClasses: + if Arch in Item.SupArchList: + Lib = Item.LibraryClass + RecommendedInstance = Item.RecommendedInstance + if Pb.LibraryClass != []: + # + # For Library + # + for Libs in Pb.LibraryClass: + for Type in Libs.SupModList: + Instance = self.FindLibraryClassInstanceOfLibrary(Lib, Arch, Type) + if Instance == None: + Instance = RecommendedInstance + Pb.LibraryClasses[(Lib, Type)] = Instance + else: + # + # For Module + # + Instance = self.FindLibraryClassInstanceOfModule(Lib, Arch, Pb.ModuleType, Inf) + if Instance == None: + Instance = RecommendedInstance + Pb.LibraryClasses[(Lib, Pb.ModuleType)] = Instance + + # + # Libraries + # + for Item in Module.Libraries: + if Arch in Item.SupArchList: + Pb.Libraries.append(Item.Library) + + # + # Pcds + # + for Item in Module.PcdCodes: + if Arch in Item.SupArchList: + Name = Item.CName + Guid = Item.TokenSpaceGuidCName + Type = Item.ItemType + Pb.Pcds[(Name, Guid)] = self.FindPcd(Arch, Inf, Name, Guid, Type) + + # + # Add to database + # + self.Build[Arch].ModuleDatabase[Inf] = Pb + Pb = None + + ## Update Libraries Of Platform Database + # + # @param InfList: A list for all inf files + # + def UpdateLibrariesOfPlatform(self, InfList = []): + for Arch in self.SupArchList: + PlatformDatabase = self.Build[Arch].PlatformDatabase + for Dsc in PlatformDatabase: + Platform = PlatformDatabase[Dsc] + for Inf in Platform.Modules: + if not self.IsModuleDefinedInPlatform(Inf, Arch, InfList): + continue + Module = self.Build[Arch].ModuleDatabase[Inf] + if Module.LibraryClass == None or Module.LibraryClass == []: + self.UpdateLibrariesOfModule(Platform, Module, Arch) + for Key in Module.LibraryClasses: + Lib = Module.LibraryClasses[Key] + if Lib not in Platform.LibraryInstances: + Platform.LibraryInstances.append(Lib) + + + ## Update Libraries Of Module Database + # + # @param Module: The module need to be updated libraries + # @param Arch: The supportted arch of the module + # + def UpdateLibrariesOfModule(self, Platform, Module, Arch): + ModuleDatabase = self.Build[Arch].ModuleDatabase + ModuleType = Module.ModuleType + + # check R8 module + if Module.AutoGenVersion < 0x00010005: + EdkLogger.verbose("") + EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch)) + LibraryConsumerList = [Module] + + # "CompilerStub" is a must for R8 modules + Module.Libraries.append("CompilerStub") + while len(LibraryConsumerList) > 0: + M = LibraryConsumerList.pop() + for LibraryName in M.Libraries: + if LibraryName not in Platform.Libraries: + EdkLogger.warn("AutoGen", "Library [%s] is not found" % LibraryName, + ExtraData="\t%s [%s]" % (str(Module), Arch)) + continue + + LibraryFile = Platform.Libraries[LibraryName] + if (LibraryName, ModuleType) not in Module.LibraryClasses: + Module.LibraryClasses[LibraryName, ModuleType] = LibraryFile + LibraryConsumerList.append(ModuleDatabase[LibraryFile]) + EdkLogger.verbose("\t" + LibraryName + " : " + LibraryFile) + return + + # R9 module + LibraryConsumerList = [Module] + Constructor = [] + ConsumedByList = sdict() + LibraryInstance = sdict() + + EdkLogger.verbose("") + EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch)) + while len(LibraryConsumerList) > 0: + M = LibraryConsumerList.pop() + for Key, LibraryPath in M.LibraryClasses.iteritems(): + # The "Key" is in format of (library_class_name, supported_module_type) + if ModuleType != "USER_DEFINED" and ModuleType not in Key: + EdkLogger.debug(EdkLogger.DEBUG_3, "%s for module type %s is not supported (%s)" % (Key + (LibraryPath,))) + continue + + LibraryClassName = Key[0] + if LibraryClassName not in LibraryInstance or LibraryInstance[LibraryClassName] == None: + if LibraryPath == None or LibraryPath == "": + LibraryInstance[LibraryClassName] = None + continue + LibraryModule = ModuleDatabase[LibraryPath] + LibraryInstance[LibraryClassName] = LibraryModule + LibraryConsumerList.append(LibraryModule) + EdkLogger.verbose("\t" + LibraryClassName + " : " + str(LibraryModule)) + elif LibraryPath == None or LibraryPath == "": + continue + else: + LibraryModule = LibraryInstance[LibraryClassName] + + if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor: + Constructor.append(LibraryModule) + + if LibraryModule not in ConsumedByList: + ConsumedByList[LibraryModule] = [] + if M != Module: + if M in ConsumedByList[LibraryModule]: + continue + ConsumedByList[LibraryModule].append(M) + # + # Initialize the sorted output list to the empty set + # + SortedLibraryList = [] + # + # Q <- Set of all nodes with no incoming edges + # + LibraryList = [] #LibraryInstance.values() + Q = [] + for LibraryClassName in LibraryInstance: + M = LibraryInstance[LibraryClassName] + if M == None: + EdkLogger.error("AutoGen", AUTOGEN_ERROR, + "Library instance for library class [%s] is not found" % LibraryClassName, + ExtraData="\t%s [%s]" % (str(Module), Arch)) + LibraryList.append(M) + # + # check if there're duplicate library classes + # + for Lc in M.LibraryClass: + if Lc.SupModList != None and ModuleType not in Lc.SupModList: + EdkLogger.error("AutoGen", AUTOGEN_ERROR, + "Module type [%s] is not supported by library instance [%s]" % (ModuleType, str(M)), + ExtraData="\t%s" % str(Module)) + + if Lc.LibraryClass in LibraryInstance and str(M) != str(LibraryInstance[Lc.LibraryClass]): + EdkLogger.error("AutoGen", AUTOGEN_ERROR, + "More than one library instance found for library class [%s] in module [%s]" % (Lc.LibraryClass, Module), + ExtraData="\t%s\n\t%s" % (LibraryInstance[Lc.LibraryClass], str(M)) + ) + if ConsumedByList[M] == []: + Q.insert(0, M) + # + # while Q is not empty do + # + while Q != []: + # + # remove node from Q + # + Node = Q.pop() + # + # output Node + # + SortedLibraryList.append(Node) + # + # for each node Item with an edge e from Node to Item do + # + for Item in LibraryList: + if Node not in ConsumedByList[Item]: + continue + # + # remove edge e from the graph + # + ConsumedByList[Item].remove(Node) + # + # If Item has no other incoming edges then + # + if ConsumedByList[Item] == []: + # + # insert Item into Q + # + Q.insert(0, Item) + + EdgeRemoved = True + while Q == [] and EdgeRemoved: + EdgeRemoved = False + # + # for each node Item with a Constructor + # + for Item in LibraryList: + if Item in Constructor: + # + # for each Node without a constructor with an edge e from Item to Node + # + for Node in ConsumedByList[Item]: + if Node not in Constructor: + # + # remove edge e from the graph + # + ConsumedByList[Item].remove(Node) + EdgeRemoved = True + if ConsumedByList[Item] == []: + # + # insert Item into Q + # + Q.insert(0, Item) + break + if Q != []: + break + + # + # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle + # + for Item in LibraryList: + if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1: + ErrorMessage = 'Library [%s] with constructors has a cycle' % str(Item) + EdkLogger.error("AutoGen", AUTOGEN_ERROR, ErrorMessage, + "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])) + if Item not in SortedLibraryList: + SortedLibraryList.append(Item) + + # + # Build the list of constructor and destructir names + # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order + # + SortedLibraryList.reverse() + Module.LibraryClasses = sdict() + for L in SortedLibraryList: + for Lc in L.LibraryClass: + Module.LibraryClasses[Lc.LibraryClass, ModuleType] = str(L) + # + # Merge PCDs from library instance + # + for Key in L.Pcds: + if Key not in Module.Pcds: + LibPcd = L.Pcds[Key] + Module.Pcds[Key] = self.FindPcd(Arch, str(Module), LibPcd.TokenCName, LibPcd.TokenSpaceGuidCName, LibPcd.Type) + # + # Merge GUIDs from library instance + # + for CName in L.Guids: + if CName not in Module.Guids: + Module.Guids.append(CName) + # + # Merge Protocols from library instance + # + for CName in L.Protocols: + if CName not in Module.Protocols: + Module.Protocols.append(CName) + # + # Merge Ppis from library instance + # + for CName in L.Ppis: + if CName not in Module.Ppis: + Module.Ppis.append(CName) + + ## GenBuildDatabase + # + # Generate build database for all arches + # + # @param PcdsSet: Pcd list for override from Fdf parse result + # @param InfList: Inf list for override from Fdf parse result + # + def GenBuildDatabase(self, PcdsSet = {}, InfList = []): + # + # Add additional inf file defined in Fdf file + # + for InfFile in InfList: + self.AddToInfDatabase(NormPath(InfFile)) + + # + # Generate PlatformDatabase, PackageDatabase and ModuleDatabase + # + self.GenPackageDatabase() + self.GenPlatformDatabase(PcdsSet) + self.GenModuleDatabase(InfList) + + self.Db.Close() + + # + # Update Libraries Of Platform + # + self.UpdateLibrariesOfPlatform(InfList) + + # + # Output used Pcds not found in DSC file + # + self.ShowUnFoundPcds() + + ## ShowUnFoundPcds() + # + # If there is any pcd used but not defined in DSC + # Print warning message on screen and output a list of pcds + # + def ShowUnFoundPcds(self): + if self.UnFoundPcdInDsc != {}: + WrnMessage = '**** WARNING ****\n' + WrnMessage += 'The following Pcds were not defined in the DSC file: %s\n' % self.DscFileName + WrnMessage += 'The default values were obtained from the DEC file that declares the PCD and the PCD default value\n' + for (Guid, Name, Type, Arch) in self.UnFoundPcdInDsc: + Dec = self.UnFoundPcdInDsc[(Guid, Name, Type, Arch)] + Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds + if (Name, Guid, Type) in Pcds: + Pcd = Pcds[(Name, Guid, Type)] + PcdItemTypeUsed = Pcd.Type + DefaultValue = Pcd.DefaultValue + WrnMessage += '%s.%s: Defined in file %s, PcdItemType is Pcds%s, DefaultValue is %s\n' % (Guid, Name, Dec, PcdItemTypeUsed, DefaultValue) + EdkLogger.verbose(WrnMessage) + + ## Create a full path with workspace dir + # + # Convert Filename with workspace dir to create a full path + # + # @param Filename: The filename need to be added workspace dir + # + # @retval string Full path + # + def WorkspaceFile(self, Filename): + return WorkspaceFile(self.WorkspaceDir, Filename) + + ## Update LibraryClass of Module + # + # If a module of a platform has its own override libraryclass but the libraryclass not defined in the module + # Add this libraryclass to the module + # + # @param InfFileName: InfFileName specificed in platform + # @param LibraryClass: LibraryClass specificed in platform + # @param Arch: Supportted Arch + # @param InstanceFilePath: InstanceFilePath specificed in platform + # + def UpdateLibraryClassOfModule(self, InfFileName, LibraryClass, Arch, InstanceFilePath): + # + # Update the library instance itself to add this libraryclass name + # + LibraryModule = self.InfDatabase[InstanceFilePath].Module + LibList = LibraryModule.Header[Arch].LibraryClass + NotFound = True + for Lib in LibList: + # + # Find this LibraryClass + # + if Lib.LibraryClass == LibraryClass: + NotFound = False; + break; + if NotFound: + NewLib = LibraryClassClass() + NewLib.LibraryClass = LibraryClass + NewLib.SupModuleList = DataType.SUP_MODULE_LIST # LibraryModule.Header[Arch].ModuleType.split() + LibraryModule.Header[Arch].LibraryClass.append(NewLib) + + # + # Add it to LibraryClasses Section for the module which is using the library + # + Module = self.InfDatabase[InfFileName].Module + LibList = Module.LibraryClasses + NotFound = True + for Lib in LibList: + # + # Find this LibraryClass + # + if Lib.LibraryClass == LibraryClass: + if Arch in Lib.SupArchList: + return + else: + Lib.SupArchList.append(Arch) + return + if NotFound: + Lib = LibraryClassClass() + Lib.LibraryClass = LibraryClass + Lib.SupArchList = [Arch] + Module.LibraryClasses.append(Lib) + + ## Add Inf file to InfDatabase + # + # Create a Inf instance for input inf file and add it to InfDatabase + # + # @param InfFileName: The InfFileName need to be added to database + # + def AddToInfDatabase(self, InfFileName): + File = self.WorkspaceFile(InfFileName) + if os.path.exists(File) and os.path.isfile(File): + if InfFileName not in self.InfDatabase: + self.InfDatabase[InfFileName] = Inf(File, False, True, self.WorkspaceDir, self.Db, self.SupArchList) + else: + EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData=File) + + ## Add Dec file to DecDatabase + # + # Create a Dec instance for input dec file and add it to DecDatabase + # + # @param DecFileName: The DecFileName need to be added to database + # + def AddToDecDatabase(self, DecFileName): + File = self.WorkspaceFile(DecFileName) + if os.path.exists(File) and os.path.isfile(File): + if DecFileName not in self.DecDatabase: + self.DecDatabase[DecFileName] = Dec(File, False, True, self.WorkspaceDir, self.Db, self.SupArchList) + else: + EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData=File) + + ## Search LibraryClass Instance for Module + # + # Search PlatformBuildDatabase to find LibraryClass Instance for Module + # Return the instance if found + # + # @param Lib: Input value for Library Class Name + # @param Arch: Supportted Arch + # @param ModuleType: Supportted ModuleType + # @param ModuleName: Input value for Module Name + # + # @retval string Found LibraryClass Instance file path + # + def FindLibraryClassInstanceOfModule(self, Lib, Arch, ModuleType, ModuleName): + # + # First find if exist in of from dsc file + # + for Dsc in self.DscDatabase.keys(): + Platform = self.DscDatabase[Dsc].Platform + for Module in Platform.Modules.ModuleList: + if Arch in Module.SupArchList: + if Module.FilePath == ModuleName: + for LibraryClass in Module.LibraryClasses.LibraryList: + if LibraryClass.Name == Lib: + return LibraryClass.FilePath + # + #Second find if exist in of from dsc file + # + return self.FindLibraryClassInstanceOfLibrary(Lib, Arch, ModuleType) + + ## Search LibraryClass Instance for Library + # + # Search PlatformBuildDatabase to find LibraryClass Instance for Library + # Return the instance if found + # + # @param Lib: Input value for Library Class Name + # @param Arch: Supportted Arch + # @param Type: Supportted Library Usage Type + # + # @retval string Found LibraryClass Instance file path + # @retval None Not Found + # + def FindLibraryClassInstanceOfLibrary(self, Lib, Arch, Type): + for Dsc in self.DscDatabase.keys(): + Platform = self.DscDatabase[Dsc].Platform + if (Lib, Type) in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses: + return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, Type)] + elif (Lib, '') in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses: + return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, '')] + return None + + ## Find BuildOptions + # + # Search DscDatabase to find component definition of ModuleName + # Override BuildOption if it is defined in component + # + # @param Arch: Supportted Arch + # @param ModuleName: The module which has buildoption definition in component of platform + # @param BuildOptions: The set of all buildopitons + # + def FindBuildOptions(self, Arch, ModuleName, BuildOptions): + for Dsc in self.DscDatabase.keys(): + # + # First find if exist in of from dsc file + # if find, use that override the one defined in inf file + # + Platform = self.DscDatabase[Dsc].Platform + for Module in Platform.Modules.ModuleList: + if Arch in Module.SupArchList: + if Module.FilePath == ModuleName: + for BuildOption in Module.ModuleSaBuildOption.BuildOptionList: + # + # Add to BuildOptions + # + BuildOptions[(BuildOption.ToolChainFamily, BuildOption.ToolChain)] = BuildOption.Option + + ## Find Pcd + # + # Search platform database, package database, module database and PcdsSet from Fdf + # Return found Pcd + # + # @param Arch: Supportted Arch + # @param ModuleName: The module which has pcd definition in component of platform + # @param Name: Name of Pcd + # @param Guid: Guid of Pcd + # @param Type: Type of Pcd + # + # @retval PcdClassObject An instance for PcdClassObject with all members filled + # + def FindPcd(self, Arch, ModuleName, Name, Guid, Type): + NewType = '' + DatumType = '' + Value = '' + Token = '' + MaxDatumSize = '' + SkuInfoList = {} + IsOverrided = False + IsFoundInDsc = False + IsFoundInDec = False + FoundInDecFile = '' + + # + # Second get information from platform database + # + OwnerPlatform = '' + for Dsc in self.Build[Arch].PlatformDatabase.keys(): + Pcds = self.Build[Arch].PlatformDatabase[Dsc].Pcds + if (Name, Guid) in Pcds: + OwnerPlatform = Dsc + Pcd = Pcds[(Name, Guid)] + if Pcd.Type != '' and Pcd.Type != None: + NewType = Pcd.Type + if NewType in DataType.PCD_DYNAMIC_TYPE_LIST: + NewType = DataType.TAB_PCDS_DYNAMIC + elif NewType in DataType.PCD_DYNAMIC_EX_TYPE_LIST: + NewType = DataType.TAB_PCDS_DYNAMIC_EX + else: + NewType = Type + + if Type != '' and Type != NewType: + ErrorMsg = "PCD %s.%s is declared as [%s] in module\n\t%s\n\n"\ + " But it's used as [%s] in platform\n\t%s"\ + % (Guid, Name, Type, ModuleName, NewType, OwnerPlatform) + EdkLogger.error("AutoGen", PARSER_ERROR, ErrorMsg) + + + if Pcd.DatumType != '' and Pcd.DatumType != None: + DatumType = Pcd.DatumType + if Pcd.TokenValue != '' and Pcd.TokenValue != None: + Token = Pcd.TokenValue + if Pcd.DefaultValue != '' and Pcd.DefaultValue != None: + Value = Pcd.DefaultValue + if Pcd.MaxDatumSize != '' and Pcd.MaxDatumSize != None: + MaxDatumSize = Pcd.MaxDatumSize + SkuInfoList = Pcd.SkuInfoList + + IsOverrided = True + IsFoundInDsc = True + break + + # + # Third get information from of from module database + # + for Dsc in self.DscDatabase.keys(): + for Module in self.DscDatabase[Dsc].Platform.Modules.ModuleList: + if Arch in Module.SupArchList: + if Module.FilePath == ModuleName: + for Pcd in Module.PcdBuildDefinitions: + if (Name, Guid) == (Pcd.CName, Pcd.TokenSpaceGuidCName): + if Pcd.DefaultValue != '': + Value = Pcd.DefaultValue + if Pcd.MaxDatumSize != '': + MaxDatumSize = Pcd.MaxDatumSize + + IsFoundInDsc = True + IsOverrided = True + break + + # + # First get information from package database + # + Pcd = None + if NewType == '': + if Type != '': + PcdTypeList = [Type] + else: + PcdTypeList = ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"] + + for Dec in self.Build[Arch].PackageDatabase.keys(): + Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds + for PcdType in PcdTypeList: + if (Name, Guid, PcdType) in Pcds: + Pcd = Pcds[(Name, Guid, PcdType)] + NewType = PcdType + IsOverrided = True + IsFoundInDec = True + FoundInDecFile = Dec + break + else: + continue + break + else: + for Dec in self.Build[Arch].PackageDatabase.keys(): + Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds + if (Name, Guid, NewType) in Pcds: + Pcd = Pcds[(Name, Guid, NewType)] + IsOverrided = True + IsFoundInDec = True + FoundInDecFile = Dec + break + + if not IsFoundInDec: + ErrorMsg = "Pcd '%s.%s [%s]' defined in module '%s' is not found in any package for Arch '%s'" % (Guid, Name, NewType, ModuleName, Arch) + EdkLogger.error("AutoGen", PARSER_ERROR, ErrorMsg) + + # + # Not found in any platform and fdf + # + if not IsFoundInDsc: + Value = Pcd.DefaultValue + if NewType.startswith("Dynamic") and SkuInfoList == {}: + SkuIds = self.Build[Arch].PlatformDatabase.values()[0].SkuIds + SkuInfoList['DEFAULT'] = SkuInfoClass(SkuIdName='DEFAULT', SkuId=SkuIds['DEFAULT'], DefaultValue=Value) + self.UnFoundPcdInDsc[(Guid, Name, NewType, Arch)] = FoundInDecFile + #elif Type != '' and NewType.startswith("Dynamic"): + # NewType = Pcd.Type + DatumType = Pcd.DatumType + if Token in [None, '']: + Token = Pcd.TokenValue + if DatumType == "VOID*" and MaxDatumSize in ['', None]: + EdkLogger.verbose("No MaxDatumSize specified for PCD %s.%s in module [%s]" % (Guid, Name, ModuleName)) + if Value[0] == 'L': + MaxDatumSize = str(len(Value) * 2) + elif Value[0] == '{': + MaxDatumSize = str(len(Value.split(','))) + else: + MaxDatumSize = str(len(Value)) + + return PcdClassObject(Name, Guid, NewType, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided) + + ## Find Supportted Module List Of LibraryClass + # + # Search in InfDatabase, find the supmodulelist of the libraryclass + # + # @param LibraryClass: LibraryClass name for search + # @param OverridedLibraryClassList: A list of all LibraryClass + # @param Arch: Supportted Arch + # + # @retval list SupModuleList + # + def FindSupModuleListOfLibraryClass(self, LibraryClass, OverridedLibraryClassList, Arch): + Name = LibraryClass.Name + FilePath = LibraryClass.FilePath + SupModuleList = copy.copy(LibraryClass.SupModuleList) + + # + # If the SupModuleList means all, remove overrided module types of platform + # + if SupModuleList == DataType.SUP_MODULE_LIST: + EdkLogger.debug(EdkLogger.DEBUG_3, "\tLibraryClass %s supports all module types" % Name) + for Item in OverridedLibraryClassList: + # + # Find a library class (Item) with the same name + # + if Item.Name == Name: + # + # Do nothing if it is itself + # + if Item.SupModuleList == DataType.SUP_MODULE_LIST: + continue + # + # If not itself, check arch first + # + if Arch in LibraryClass.SupArchList: + # + # If arch is supportted, remove all related module type + # + if Arch in Item.SupArchList: + for ModuleType in Item.SupModuleList: + EdkLogger.debug(EdkLogger.DEBUG_3, "\tLibraryClass %s has specific defined module types" % Name) + if ModuleType in SupModuleList: + SupModuleList.remove(ModuleType) + + return SupModuleList + + ## Find Module inf Platform + # + # Check if the module is defined in of + # + # @param Inf: Inf file (Module) need to be searched + # @param Arch: Supportted Arch + # @param InfList: A list for all Inf file + # + # @retval True Mudule Found + # @retval Flase Module Not Found + # + def IsModuleDefinedInPlatform(self, Inf, Arch, InfList): + for Dsc in self.DscDatabase.values(): + for LibraryClass in Dsc.Platform.LibraryClasses.LibraryList: + if Inf == LibraryClass.FilePath and Arch in LibraryClass.SupArchList: + return True + for Module in Dsc.Platform.Modules.ModuleList: + if Inf == Module.FilePath and Arch in Module.SupArchList: + return True + for Item in Module.LibraryClasses.LibraryList: + if Inf == Item.FilePath: + return True + for Library in Dsc.Platform.Libraries.LibraryList: + if Inf == Library.FilePath and Arch in Library.SupArchList: + return True + + return False + + ## Show all content of the workspacebuild + # + # Print each item of the workspacebuild with (Key = Value) pair + # + def ShowWorkspaceBuild(self): + print self.DscDatabase + print self.InfDatabase + print self.DecDatabase + print 'SupArchList', self.SupArchList + print 'BuildTarget', self.BuildTarget + print 'SkuId', self.SkuId + + for Arch in self.SupArchList: + print Arch + print 'Platform' + for Platform in self.Build[Arch].PlatformDatabase.keys(): + P = self.Build[Arch].PlatformDatabase[Platform] + print 'DescFilePath = ', P.DescFilePath + print 'PlatformName = ', P.PlatformName + print 'Guid = ', P.Guid + print 'Version = ', P.Version + print 'OutputDirectory = ', P.OutputDirectory + print 'FlashDefinition = ', P.FlashDefinition + print 'SkuIds = ', P.SkuIds + print 'Modules = ', P.Modules + print 'LibraryClasses = ', P.LibraryClasses + print 'Pcds = ', P.Pcds + for item in P.Pcds.keys(): + print P.Pcds[item] + print 'BuildOptions = ', P.BuildOptions + print '' + # End of Platform + + print 'package' + for Package in self.Build[Arch].PackageDatabase.keys(): + P = self.Build[Arch].PackageDatabase[Package] + print 'DescFilePath = ', P.DescFilePath + print 'PackageName = ', P.PackageName + print 'Guid = ', P.Guid + print 'Version = ', P.Version + print 'Protocols = ', P.Protocols + print 'Ppis = ', P.Ppis + print 'Guids = ', P.Guids + print 'Includes = ', P.Includes + print 'LibraryClasses = ', P.LibraryClasses + print 'Pcds = ', P.Pcds + for item in P.Pcds.keys(): + print P.Pcds[item] + print '' + # End of Package + + print 'module' + for Module in self.Build[Arch].ModuleDatabase.keys(): + P = self.Build[Arch].ModuleDatabase[Module] + print 'DescFilePath = ', P.DescFilePath + print 'BaseName = ', P.BaseName + print 'ModuleType = ', P.ModuleType + print 'Guid = ', P.Guid + print 'Version = ', P.Version + print 'CustomMakefile = ', P.CustomMakefile + print 'Specification = ', P.Specification + print 'Shadow = ', P.Shadow + print 'PcdIsDriver = ', P.PcdIsDriver + for Lib in P.LibraryClass: + print 'LibraryClassDefinition = ', Lib.LibraryClass, 'SupModList = ', Lib.SupModList + print 'ModuleEntryPointList = ', P.ModuleEntryPointList + print 'ModuleUnloadImageList = ', P.ModuleUnloadImageList + print 'ConstructorList = ', P.ConstructorList + print 'DestructorList = ', P.DestructorList + + print 'Binaries = ' + for item in P.Binaries: + print item.BinaryFile, item.FeatureFlag, item.SupArchList + print 'Sources = ' + for item in P.Sources: + print item.SourceFile + print 'LibraryClasses = ', P.LibraryClasses + print 'Protocols = ', P.Protocols + print 'Ppis = ', P.Ppis + print 'Guids = ', P.Guids + print 'Includes = ', P.Includes + print 'Packages = ', P.Packages + print 'Pcds = ', P.Pcds + for item in P.Pcds.keys(): + print P.Pcds[item] + print 'BuildOptions = ', P.BuildOptions + print 'Depex = ', P.Depex + print '' + # End of Module + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + print 'Start!', time.strftime('%H:%M:%S', time.localtime()) + EdkLogger.Initialize() + EdkLogger.SetLevel(EdkLogger.QUIET) + + W = os.getenv('WORKSPACE') + Ewb = WorkspaceBuild('Nt32Pkg/Nt32Pkg.dsc', W) + Ewb.GenBuildDatabase({('PcdDevicePathSupportDevicePathFromText', 'gEfiMdeModulePkgTokenSpaceGuid') : 'KKKKKKKKKKKKKKKKKKKKK'}, ['Test.Inf']) + print 'Done!', time.strftime('%H:%M:%S', time.localtime()) + Ewb.ShowWorkspaceBuild() -- cgit v1.2.3