EdkIIWorkspaceBuild.py revision 4fd606d1f5abe38e1f42c38de1d2e895166bd0f4
## @file
# This file is used to define each component of the build database
#
# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
# 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.UefiSpecificationVersion
Pb.Specification[TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION] = ModuleHeader.UefiSpecificationVersion
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 Edk 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 Edk 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
# EdkII 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 <LibraryClass> of <Components> 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 <LibraryClass> of <LibraryClasses> 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 <BuildOptions> of <Components> 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 <Pcd> of <Compontents> 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 <Compentent> of <Platform>
#
# @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()