system76-edk2/BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py
Hess Chen 1be2ed90a2 There is a limitation on WINDOWS OS for the length of entire file path can’t be larger than 255. There is an OS API provided by Microsoft to add “\\?\” before the path header to support the long file path. Enable this feature on basetools.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Hess Chen <hesheng.chen@intel.com>
Reviewed-by: Yingke Liu <yingke.d.liu@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15809 6f19259b-4bc3-4df7-8a09-765794883524
2014-08-15 03:06:48 +00:00

1671 lines
70 KiB
Python

## @file
# This file is used to define each component of the build database
#
# Copyright (c) 2007 - 2014, 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 Common.LongFilePathOs as 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 | AARCH64
# @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()