audk/Tools/Python/buildgen/SurfaceAreaElement.py

1556 lines
66 KiB
Python

#!/usr/bin/env python
# Copyright (c) 2007, Intel Corporation
# All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
"""Framework SurfaceArea Elemments"""
#
# TODO: FFS layout, Flash, FV, PCD
#
import os, sys, re, getopt, string, glob, xml.dom.minidom, pprint, time, copy, shelve, pickle
from XmlRoutines import *
import FrameworkElement
import BuildConfig
################################################################################
##
## Convert given list to a string in the format like: [a, b, c]
##
################################################################################
def ListString(lst):
return "[%s]" % ",".join(lst)
class SurfaceAreaElement:
"""Base class for Surface Area XML element"""
_ModuleTypes = ('BASE', 'SEC', 'PEI_CORE', 'PEIM', 'DXE_CORE', 'DXE_DRIVER',
'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'DXE_SMM_DRIVER',
'TOOL', 'UEFI_DRIVER', 'UEFI_APPLICATION', 'USER_DEFINED')
_GuidTypes = ('DATA_HUB_RECORD', 'EFI_EVENT', 'EFI_SYSTEM_CONFIGURATION_TABLE',
'EFI_VARIABLE', 'GUID', 'HII_PACKAGE_LIST', 'HOB', 'TOKEN_SPACE_GUID')
_Archs = ('EBC', 'IA32', 'X64', 'IPF', 'ARM', 'PPC')
_Usages = ('ALWAYS_CONSUMED', 'SOMETIMES_CONSUMED', 'ALWAYS_PRODUCED',
'SOMETIMES_PRODUCED', 'TO_START', 'BY_START', 'PRIVATE')
_FileTypes = {
".c" : "CCode",
".C" : "CCode",
".cpp" : "CCode",
".Cpp" : "CCode",
".CPP" : "CCode",
".h" : "CHeader",
".H" : "CHeader",
".asm" : "ASM",
".Asm" : "Assembly",
".ASM" : "Assembly",
".s" : "IpfAssembly",
".S" : "GccAssembly",
".uni" : "UNI",
".Uni" : "Unicode",
".UNI" : "Unicode",
".vfr" : "VFR",
".Vfr" : "VFR",
".VFR" : "VFR",
".dxs" : "DPX",
".Dxs" : "DPX",
".DXS" : "DPX",
".fv" : "FirmwareVolume",
".Fv" : "FirmwareVolume",
".FV" : "FirmwareVolume",
".efi" : "EFI",
".Efi" : "EFI",
".EFI" : "EFI",
".SEC" : "FFS",
".PEI" : "FFS",
".DXE" : "FFS",
".APP" : "FFS",
".FYI" : "FFS",
".FFS" : "FFS",
".bmp" : "BMP",
".i" : "PPCode",
".asl" : "ASL",
".Asl" : "ASL",
".ASL" : "ASL",
}
_ToolMapping = {
"CCode" : "CC",
"CHeader" : "",
"ASM" : "ASM",
"Assembly" : "ASM",
"IpfAssembly" : "ASM",
"GccAssembly" : "ASM",
"UNI" : "",
"Unicode" : "",
"VFR" : "",
"DPX" : "",
"FirmwareVolume" : "",
"EFI" : "",
"FFS" : "",
"PPCode" : "PP",
"BMP" : "",
}
_BuildableFileTypes = ("CCode", "ASM", "Assembly", "IpfAssembly", "GccAssembly", "UNI", "Unicode", "VFR", "DPX", "EFI")
def __init__(self, workspace, owner=None, dom=None, parse=True, postprocess=True):
self._Workspace = workspace
if owner == None: self._Owner = ""
else: self._Owner = owner
if dom == None: self._Root = ""
else: self._Root = dom
self._Elements = {}
if parse: self.Parse()
if postprocess: self.Postprocess()
def Parse(self):
"""Parse the XML element in DOM form"""
pass
def Postprocess(self):
"""Re-organize the original information form XML DOM into a format which can be used directly"""
pass
def GetArchList(self, dom):
"""Parse the SupArchList attribute. If not spcified, return all ARCH supported"""
archs = XmlAttribute(dom, "SupArchList").split()
if archs == []:
if self._Owner.Archs != []:
archs = self._Owner.Archs
elif self._Workspace.ActiveArchs != []:
archs = self._Workspace.ActiveArchs
elif self._Workspace.ActivePlatform != "" and self._Workspace.ActivePlatform.Archs != []:
archs = self._Workspace.ActivePlatform.Archs
else:
archs = self._Archs
return archs
def GetModuleTypeList(self, dom):
"""Parse the SupModuleList attribute. If not specified, return all supported module types"""
moduleTypes = XmlAttribute(dom, "SupModuleList").split()
if moduleTypes == []:
moduleTypes = self._ModuleTypes
return moduleTypes
def GetGuidTypeList(self, dom):
"""Parse GuidTypeList attribute. Default to GUID if not specified"""
guidTypes = XmlAttribute(dom, "GuidTypeList")
if guidTypes == []:
guidTypes = ["GUID"]
return guidTypes
def GetFeatureList(self, dom):
"""Parse FeatureFlag attribute"""
return XmlAttribute(dom, "FeatureFlag").split()
def GetToolchainTagList(self, dom):
"""Parse TagName attribute. Return all defined toolchains defined in tools_def.txt if not given"""
toolchainTagString = XmlAttribute(dom, "TagName")
if toolchainTagString == "":
return self._Workspace.ToolConfig.Toolchains
return toolchainTagString.split()
def GetToolchainFamilyList(self, dom):
"""Parse ToolChainFamily attribute. Return all defined toolchain families in tools_def.txt if not given"""
familyString = XmlAttribute(dom, "ToolChainFamily")
if familyString != "":
return familyString.split()
return self._Workspace.ToolConfig.Families
def GetTargetList(self, dom):
"""Parse BuildTargets attribute. Return all build targets defined in tools_def.txt if not given"""
targetList = XmlAttribute(dom, "BuildTargets").split()
if targetList == []:
targetList = self._Workspace.ToolConfig.Targets
return targetList
def GetUsage(self, dom):
"""Parse Usage attribute. Default to ALWAYS_CONSUMED if not given"""
usageString = XmlAttribute(dom, "Usage")
if usageString == "":
return "ALWAYS_CONSUMED"
return usageString
def GetBuildOptionList(self, dom):
"""Parse Options/Option element. Return a options dictionay with keys as (toolchain, target, arch, toolcode, attr)"""
optionList = XmlList(dom, "/Options/Option")
buildOptions = {}
for option in optionList:
targets = self.GetTargetList(option)
toolchainFamilies = self.GetToolchainFamilyList(option)
toolchainTags = self.GetToolchainTagList(option)
toolcode = XmlAttribute(option, "ToolCode")
archs = self.GetArchList(option)
flag = XmlElementData(option)
# print flag
toolchains = []
if toolchainTags != []:
toolchains = toolchainTags
elif toolchainFamilies != []:
toolchains = toolchainFamilies
else:
raise Exception("No toolchain specified for a build option: " + self._Owner.Name)
if targets == []: targets = self._Workspace.ActiveTargets
if archs == []: archs = self._Workspace.ActiveArchs
for toolchain in toolchains:
for target in targets:
for arch in archs:
buildOptions[(toolchain, target, arch, toolcode, "FLAGS")] = flag
return buildOptions
def GetFvBindingList(self, dom):
"""Parse FvBinding element. If not specified, return NULL FV"""
fvBindingList = XmlElementData(dom).split()
if fvBindingList == []:
fvBindingList = ["NULL"]
return fvBindingList
def IsBuildable(self, type):
"""Test if a file with the type can be built by a tool"""
return type in self._BuildableFileTypes
def GetToolCode(self, type):
"""Get the toolcode which must be used to build files with the type"""
toolcode = ""
if type in self._ToolMapping:
toolcode = self._ToolMapping[type]
return toolcode
def GetBoolean(self, dom):
"""Transate true/false in string form to python's True/False value"""
boolString = XmlElementData(dom).upper()
if boolString == "" or boolString == "FALSE" or boolString == "NO":
return False
else:
return True
class LibraryDeclaration(FrameworkElement.LibraryInterface, SurfaceAreaElement):
def __init__(self, workspace, package, dom):
FrameworkElement.LibraryInterface.__init__(self)
self.Package = package
SurfaceAreaElement.__init__(self, workspace, package, dom)
def Parse(self):
dom = self._Root
self.Name = XmlAttribute(dom, "Name")
self.Path = os.path.normpath(XmlElementData(XmlNode(dom, "/LibraryClass/IncludeHeader")))
self.Dir = os.path.dirname(self.Path)
attribute = XmlAttribute(dom, "RecommendedInstanceGuid")
if attribute is not '':
self.FavoriteIntance = FrameworkElement.Module()
self.FavoriteIntance.Guid = attribute
attribute = XmlAttribute(dom, "RecommendedInstanceVersion")
if attribute is not '':
if self.FavoriteIntance == "":
raise "No GUID for the recommened library instance"
self.FavoriteIntance.Version = attribute
self.Archs = self.GetArchList(dom)
self.ModuleTypes = self.GetModuleTypeList(dom)
class LibraryClass(FrameworkElement.LibraryClass, SurfaceAreaElement):
def __init__(self, workspace, module, dom):
FrameworkElement.LibraryClass.__init__(self)
SurfaceAreaElement.__init__(self, workspace, module, dom)
def Parse(self):
dom = self._Root
self.Name = XmlElementData(XmlNode(dom, "/LibraryClass/Keyword"))
self.Usage = self.GetUsage(dom)
self.Features = self.GetFeatureList(dom)
self.Archs = self.GetArchList(dom)
attribute = XmlAttribute(dom, "RecommendedInstanceGuid")
if attribute is not '':
self.FavoriteIntance = FrameworkElement.Module()
self.FavoriteIntance.Guid = attribute
attribute = XmlAttribute(dom, "RecommendedInstanceVersion")
if attribute is not '':
if self.FavoriteIntance == "":
self.FavoriteIntance = FrameworkElement.Module()
self.FavoriteIntance.Version = attribute
class SourceFile(FrameworkElement.SourceFile, SurfaceAreaElement):
def __init__(self, workspace, module, dom):
FrameworkElement.SourceFile.__init__(self)
SurfaceAreaElement.__init__(self, workspace, module, dom)
def Parse(self):
dom = self._Root
self.Path = os.path.normpath(XmlElementData(dom))
self.Dir = os.path.dirname(self.Path)
self.Type = self.GetFileType()
self.Toolchains = self.GetToolchainTagList(dom)
self.Families = self.GetToolchainFamilyList(dom)
self.Archs = self.GetArchList(dom)
self.Features = self.GetFeatureList(dom)
def GetFileType(self):
type = XmlAttribute(self._Root, "ToolCode")
if type == "":
fileName = os.path.basename(self.Path)
self.BaseName,self.Ext = os.path.splitext(fileName)
if self.Ext in self._FileTypes:
type = self._FileTypes[self.Ext]
else:
type = ""
return type
class PackageDependency(FrameworkElement.PackageDependency, SurfaceAreaElement):
def __init__(self, workspace, module, dom):
FrameworkElement.PackageDependency.__init__(self)
SurfaceAreaElement.__init__(self, workspace, module, dom)
def Parse(self):
dom = self._Root
self.GuidValue = XmlAttribute(dom, "PackageGuid").upper()
self.Version = XmlAttribute(dom, "PackageVersion")
self.Archs = self.GetArchList(dom)
self.Features = self.GetFeatureList(dom)
def Postprocess(self):
self.Package = self._Workspace.GetPackage(self.GuidValue, self.Version)
if self.Package == "": raise "No package with GUID=" + self.GuidValue + "VERSION=" + self.Version
class Protocol(FrameworkElement.Protocol, SurfaceAreaElement):
def __init__(self, workspace, module, dom):
FrameworkElement.Protocol.__init__(self)
SurfaceAreaElement.__init__(self, workspace, module, dom)
def Parse(self):
dom = self._Root
self.CName = XmlElementData(XmlNode(dom, "/Protocol/ProtocolCName"))
self.Usage = self.GetUsage(dom)
self.Archs = self.GetArchList(dom)
self.Features = self.GetFeatureList(dom)
def Postprocess(self):
for pd in self._Owner._Elements["PackageDependencies"]:
if self.CName not in pd.Package.Protocols: continue
self.GuidValue = pd.Package.Protocols[self.CName]
class ProtocolNotify(FrameworkElement.ProtocolNotify, SurfaceAreaElement):
def __init__(self, workspace, module, dom):
FrameworkElement.ProtocolNotify.__init__(self)
SurfaceAreaElement.__init__(self, workspace, module, dom)
def Parse(self):
dom = self._Root
self.CName = XmlElementData(XmlNode(dom, "/ProtocolNotify/ProtocolCName"))
self.Usage = self.GetUsage(dom)
self.Archs = self.GetArchList(dom)
self.Features = self.GetFeatureList(dom)
def Postprocess(self):
for pd in self._Owner._Elements["PackageDependencies"]:
if self.CName not in pd.Package.Protocols: continue
self.GuidValue = pd.Package.Protocols[self.CName]
class Ppi(FrameworkElement.Ppi, SurfaceAreaElement):
def __init__(self, workspace, module, dom):
FrameworkElement.Ppi.__init__(self)
SurfaceAreaElement.__init__(self, workspace, module, dom)
def Parse(self):
dom = self._Root
self.CName = XmlElementData(XmlNode(dom, "/Ppi/PpiCName"))
self.Usage = self.GetUsage(dom)
self.Archs = self.GetArchList(dom)
self.Features = self.GetFeatureList(dom)
def Postprocess(self):
for pd in self._Owner._Elements["PackageDependencies"]:
if self.CName not in pd.Package.Ppis: continue
self.GuidValue = pd.Package.Ppis[self.CName]
class PpiNotify(FrameworkElement.PpiNotify, SurfaceAreaElement):
def __init__(self, workspace, module, dom):
FrameworkElement.PpiNotify.__init__(self)
SurfaceAreaElement.__init__(self, workspace, module, dom)
def Parse(self):
dom = self._Root
self.CName = XmlElementData(XmlNode(dom, "/PpiNotify/PpiCName"))
self.Usage = self.GetUsage(dom)
self.Archs = self.GetArchList(dom)
self.Features = self.GetFeatureList(dom)
def Postprocess(self):
for pd in self._Owner._Elements["PackageDependencies"]:
if self.CName not in pd.Package.Ppis: continue
self.GuidValue = pd.Package.Ppis[self.CName]
class Guid(FrameworkElement.Guid, SurfaceAreaElement):
def __init__(self, workspace, module, dom):
FrameworkElement.Guid.__init__(self)
SurfaceAreaElement.__init__(self, workspace, module, dom)
def Parse(self):
dom = self._Root
self.CName = XmlElementData(XmlNode(dom, "/GuidCNames/GuidCName"))
self.Usage = self.GetUsage(dom)
self.Archs = self.GetArchList(dom)
self.Features = self.GetFeatureList(dom)
def Postprocess(self):
for pd in self._Owner._Elements["PackageDependencies"]:
if self.CName not in pd.Package.Guids: continue
self.GuidValue = pd.Package.Guids[self.CName]
class Extern(FrameworkElement.Extern, SurfaceAreaElement):
def __init__(self, workspace, module, dom):
FrameworkElement.Extern.__init__(self)
SurfaceAreaElement.__init__(self, workspace, module, dom)
def Parse(self):
dom = self._Root
self.Archs = self.GetArchList(dom)
self.Features = self.GetFeatureList(dom)
extern = XmlNode(dom, "/Extern/ModuleEntryPoint")
if extern is not None and extern is not '':
self.ModuleEntryPoints.append(XmlElementData(extern))
extern = XmlNode(dom, "/Extern/ModuleUnloadImage")
if extern is not None and extern is not '':
self.ModuleUnloadImages.append(XmlElementData(extern))
extern = XmlNode(dom, "/Extern/Constructor")
if extern is not None and extern is not '':
self.Constructors.append(XmlElementData(extern))
extern = XmlNode(dom, "/Extern/Destructor")
if extern is not None and extern is not '':
self.Destructors.append(XmlElementData(extern))
extern = XmlNode(dom, "/Extern/DriverBinding")
if extern is not None and extern is not '':
self.DriverBindings.append(XmlElementData(extern))
extern = XmlNode(dom, "/Extern/ComponentName")
if extern is not None and extern is not '':
self.ComponentNames.append(XmlElementData(extern))
extern = XmlNode(dom, "/Extern/DriverConfig")
if extern is not None and extern is not '':
self.DriverConfigs.append(XmlElementData(extern))
extern = XmlNode(dom, "/Extern/DriverDiag")
if extern is not None and extern is not '':
self.DriverDiags.append(XmlElementData(extern))
extern = XmlNode(dom, "/Extern/SetVirtualAddressMapCallBacks")
if extern is not None and extern is not '':
self.SetVirtualAddressMapCallBacks.append(XmlElementData(extern))
extern = XmlNode(dom, "/Extern/ExitBootServicesCallBack")
if extern is not None and extern is not '':
self.ExitBootServicesCallBacks.append(XmlElementData(extern))
class IndustryStdHeader(FrameworkElement.IncludeFile, SurfaceAreaElement):
def __init__(self, workspace, package, dom):
FrameworkElement.IncludeFile.__init__(self)
SurfaceAreaElement.__init__(self, workspace, package, dom)
def Parse(self):
dom = self._Root
self.Path = os.path.normpath(XmlElementData(XmlNode(dom, "/IndustryStdHeader/IncludeHeader")))
self.Dir = os.path.dirname(self.Path)
self.Archs = self.GetArchList(dom)
self.ModuleTypes = self.GetModuleTypeList(dom)
class PackageHeader(FrameworkElement.IncludeFile, SurfaceAreaElement):
def __init__(self, workspace, package, dom):
FrameworkElement.IncludeFile.__init__(self)
SurfaceAreaElement.__init__(self, workspace, package, dom)
def Parse(self):
dom = self._Root
self.Path = os.path.normpath(XmlElementData(dom))
self.Dir = os.path.dirname(self.Path)
self.ModuleType = XmlAttribute(dom, "ModuleType")
class GuidDeclaration(FrameworkElement.Guid, SurfaceAreaElement):
def __init__(self, workspace, package, dom):
FrameworkElement.Guid.__init__(self)
SurfaceAreaElement.__init__(self, workspace, package, dom)
def Parse(self):
dom = self._Root
self.CName = XmlElementData(XmlNode(dom, "/Entry/C_Name"))
self.GuidValue = XmlElementData(XmlNode(dom, "/Entry/GuidValue")).upper()
self.Name = XmlAttribute(dom, "Name")
self.Types = self.GetGuidTypeList(dom)
self.Archs = self.GetArchList(dom)
self.ModuleTypes = self.GetModuleTypeList(dom)
def Postprocess(self):
pass
class ProtocolDeclaration(GuidDeclaration, SurfaceAreaElement):
pass
class PpiDeclaration(GuidDeclaration, SurfaceAreaElement):
pass
class PcdDeclaration(FrameworkElement.Pcd, SurfaceAreaElement):
def __init__(self, workspace, package, dom):
FrameworkElement.Pcd.__init__(self)
SurfaceAreaElement.__init__(self, workspace, package, dom)
def Parse(self):
dom = self._Root
self.Types = XmlElementData(XmlNode(dom, "/PcdEntry/ValidUsage")).split()
self.CName = XmlElementData(XmlNode(dom, "/PcdEntry/C_Name"))
self.Token = XmlElementData(XmlNode(dom, "/PcdEntry/Token"))
self.TokenSpace = XmlElementData(XmlNode(dom, "/PcdEntry/TokenSpaceGuidCName"))
self.DatumType = XmlElementData(XmlNode(dom, "/PcdEntry/DatumType"))
self.Default = XmlElementData(XmlNode(dom, "/PcdEntry/DefaultValue"))
self.Archs = self.GetArchList(dom)
self.ModuleTypes= self.GetModuleTypeList(dom)
class LibraryInstance(FrameworkElement.PlatformModule, SurfaceAreaElement):
def __init__(self, workspace, platformModule, dom):
FrameworkElement.PlatformModule.__init__(self)
SurfaceAreaElement.__init__(self, workspace, platformModule, dom)
def Parse(self):
dom = self._Root
self.GuidValue = XmlAttribute(dom, "ModuleGuid").upper()
self.Version = XmlAttribute(dom, "ModuleVersion")
self._Elements["PackageGuid"] = XmlAttribute(dom, "PackageGuid").upper()
self._Elements["PackageVersion"] = XmlAttribute(dom, "PackageVersion")
def Postprocess(self):
self.Module = self._Workspace.GetModule(self.GuidValue, self.Version,
self._Elements["PackageGuid"], self._Elements["PackageVersion"])
self.Platform = self._Owner.Platform
self.Archs = self._Owner.Archs
self.Pcds = self._Owner.Pcds
self.BuildType = "lib"
class PlatformModule(FrameworkElement.PlatformModule, SurfaceAreaElement):
def __init__(self, workspace, platform, dom):
FrameworkElement.PlatformModule.__init__(self)
self.Platform = platform
SurfaceAreaElement.__init__(self, workspace, platform, dom)
def Parse(self):
dom = self._Root
self.GuidValue = XmlAttribute(dom, "ModuleGuid").upper()
self.Version = XmlAttribute(dom, "ModuleVersion")
self.Archs = self.GetArchList(dom)
self._Elements["PackageGuid"] = XmlAttribute(dom, "PackageGuid").upper()
self._Elements["PackageVersion"] = XmlAttribute(dom, "PackageVersion")
libraryList = XmlList(dom, "/ModuleSA/Libraries/Instance")
for lib in libraryList:
self.Libraries.append(LibraryInstance(self._Workspace, self, lib))
dom = XmlNode(dom, "/ModuleSA/ModuleSaBuildOptions")
self.FvBindings = self.GetFvBindingList(XmlNode(dom, "/ModuleSaBuildOptions/FvBinding"))
self.FfsLayouts = XmlElementData(XmlNode(dom, "/ModuleSaBuildOptions/FfsFormatKey")).split()
self.BuildOptions = self.GetBuildOptionList(XmlNode(dom, "/ModuleSaBuildOptions/Options"))
def Postprocess(self):
self.Module = self._Workspace.GetModule(self.GuidValue, self.Version,
self._Elements["PackageGuid"], self._Elements["PackageVersion"])
if self.Module == "":
raise Exception("No module found: \n\t\tGUID=%s \n\t\tVERSION=%s \n\t\tPACKAGE_GUID=%s \n\t\tPACKAGE_VERSION=%s" % (
self.GuidValue, self.Version, self._Elements["PackageGuid"], self._Elements["PackageVersion"]))
## def SetupEnvironment(self):
## self.Environment = {
## "ARCH" : "",
## "MODULE_BUILD_TARGET" : "",
## "SINGLE_MODULE_BUILD" : "",
## "PLATFORM_PREBUILD" : "",
## "PLATFORM_POSTBUILD" : "",
## "LIBS" : "",
## "SOURCE_FILES" : "",
## "ENTRYPOINT" : "_ModuleEntryPoint",
## } # name/value pairs
## self.Environment["MODULE_BUILD_TARGET"] = "platform_module_build"
class ModuleSurfaceArea(FrameworkElement.Module, SurfaceAreaElement):
def __init__(self, workspace, package, path):
FrameworkElement.Module.__init__(self)
self.Path = os.path.normpath(path)
self.Dir = os.path.dirname(self.Path)
self.FileBaseName,_ext = os.path.splitext(os.path.basename(self.Path))
self.Package = package
SurfaceAreaElement.__init__(self, workspace, package)
def _MsaHeader(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
self.Name = XmlElementData(XmlNode(dom, "/MsaHeader/ModuleName"))
self.Type = XmlElementData(XmlNode(dom, "/MsaHeader/ModuleType"))
self.GuidValue = XmlElementData(XmlNode(dom, "/MsaHeader/GuidValue")).upper()
self.Version = XmlElementData(XmlNode(dom, "/MsaHeader/Version"))
def _ModuleDefinitions(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
self.Archs = XmlElementData(XmlNode(dom, "/ModuleDefinitions/SupportedArchitectures")).split()
self.IsBinary = self.GetBoolean(XmlNode(dom, "/ModuleDefinitions/BinaryModule"))
self.BaseName = XmlElementData(XmlNode(dom, "/ModuleDefinitions/OutputFileBasename"))
def _LibraryClassDefinitions(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
lcList = []
for lc in XmlList(dom, "/LibraryClassDefinitions/LibraryClass"):
lcList.append(LibraryClass(self._Workspace, self, lc))
self._Elements["LibraryClassDefinitions"] = lcList
def _SourceFiles(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
srcList = []
for f in XmlList(dom, "/SourceFiles/Filename"):
srcList.append(SourceFile(self._Workspace, self, f))
self._Elements["SourceFiles"] = srcList
def _NonProcessedFiles(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
for f in XmlList(dom, "/NonProcessedFiles/Filename"):
self.NonProcessedFiles.append(SourceFile(self._Workspace, self, f))
def _PackageDependencies(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
pdList = []
for pkg in XmlList(dom, "/PackageDependencies/Package"):
pdList.append(PackageDependency(self._Workspace, self, pkg))
self._Elements["PackageDependencies"] = pdList
def _Protocols(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
protocolList = []
for p in XmlList(dom, "/Protocols/Protocol"):
protocolList.append(Protocol(self._Workspace, self, p))
for p in XmlList(dom, "/Protocols/ProtocolNotify"):
protocolList.append(ProtocolNotify(self._Workspace, self, p))
self._Elements["Protocols"] = protocolList
def _Ppis(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
ppiList = []
for p in XmlList(dom, "/PPIs/Ppi"):
ppiList.append(Ppi(self._Workspace, self, p))
for p in XmlList(dom, "/PPIs/PpiNotify"):
ppiList.append(PpiNotify(self._Workspace, self, p))
self._Elements["PPIs"] = ppiList
def _Guids(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
guidList = []
for g in XmlList(dom, "/Guids/GuidCNames"):
guidList.append(Guid(self._Workspace, self, g))
self._Elements["Guids"] = guidList
def _Externs(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
self.PcdIsDriver = self.GetBoolean(XmlNode(dom, "/Externs/PcdIsDriver"))
self.NeedsFlashMap_h = self.GetBoolean(XmlNode(dom, "/Externs/TianoR8FlashMap_h"))
externList = []
specs = FrameworkElement.Extern()
specs.Archs = self._Archs
externList.append(specs)
for spec in XmlList(dom, "/Externs/Specification"):
specs.Specifications.append(XmlElementData(spec))
for ext in XmlList(dom, "/Externs/Extern"):
externList.append(Extern(self._Workspace, self, ext))
self._Elements["Externs"] = externList
def _ModuleBuildOptions(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
self.BuildOptions = self.GetBuildOptionList(XmlNode(dom, "/ModuleBuildOptions/Options"))
def _UserExtensions(self, xpath):
domList = XmlList(self._Root, xpath)
if domList == []: return
for extension in domList:
userId = XmlAttribute(extension, "UserID")
identifier = XmlAttribute(extension, "Identifier")
if userId == '' or identifier == '':
raise Exception("No UserId or Identifier specified")
if userId != "TianoCore": continue
if identifier not in self.UserExtensions:
self.UserExtensions[identifier] = []
contentList = self.UserExtensions[identifier]
for node in extension.childNodes:
#print node.nodeType
contentList.append(node.cloneNode(True))
def Parse(self):
fileFullPath = self._Workspace.SubPath(os.path.dirname(self.Package.Path), self.Path)
self._Root = xml.dom.minidom.parse(fileFullPath)
assert self._Root.documentElement.tagName == "ModuleSurfaceArea"
# print " Parsing...",self.Path
self._MsaHeader("/ModuleSurfaceArea/MsaHeader")
self._ModuleDefinitions("/ModuleSurfaceArea/ModuleDefinitions")
self._PackageDependencies("/ModuleSurfaceArea/PackageDependencies")
self._LibraryClassDefinitions("/ModuleSurfaceArea/LibraryClassDefinitions")
self._SourceFiles("/ModuleSurfaceArea/SourceFiles")
self._NonProcessedFiles("/ModuleSurfaceArea/NonProcessedFiles")
self._Protocols("/ModuleSurfaceArea/Protocols")
self._Ppis("/ModuleSurfaceArea/Ppis")
self._Guids("/ModuleSurfaceArea/Guids")
self._Externs("/ModuleSurfaceArea/Externs")
self._ModuleBuildOptions("/ModuleSurfaceArea/ModuleBuildOptions")
self._UserExtensions("/ModuleSurfaceArea/UserExtensions")
def Postprocess(self):
# resolve package dependency
if self._Elements.has_key("PackageDependencies"):
for pd in self._Elements["PackageDependencies"]:
package = pd.Package
if self.Type not in package.PackageIncludes:
print "! Module type %s is not supported in the package %s" % (self.Type, package.Name)
for arch in pd.Archs:
if arch not in self.IncludePaths:
self.IncludePaths[arch] = []
self.IncludePaths[arch].append(package.SubPath("Include"))
self.IncludePaths[arch].append(package.SubPath("Include", arch.capitalize()))
if arch not in self.IncludeFiles:
self.IncludeFiles[arch] = []
if self.Type in package.PackageIncludes:
for path in package.PackageIncludes[self.Type]:
self.IncludeFiles[arch].append(package.SubPath(path))
# resolve library class
if self._Elements.has_key("LibraryClassDefinitions"):
for lc in self._Elements["LibraryClassDefinitions"]:
lc.Interface = self.GetLibraryInterface(lc.Name)
if "ALWAYS_PRODUCED" in lc.Usage:
self.IsLibrary = True
lc.Interface.Instances.append(self)
else:
lc.Interface.Consumers.append(self)
for arch in lc.Archs:
if arch not in self.LibraryClasses:
self.LibraryClasses[arch] = []
self.LibraryClasses[arch].append(lc)
# expand source files
if self._Elements.has_key("SourceFiles"):
for src in self._Elements["SourceFiles"]:
for arch in src.Archs:
if arch not in self.SourceFiles:
self.SourceFiles[arch] = {}
if src.Type not in self.SourceFiles[arch]:
self.SourceFiles[arch][src.Type] = []
self.SourceFiles[arch][src.Type].append(src)
# expand guids
if self._Elements.has_key("Guids"):
for guid in self._Elements["Guids"]:
for arch in guid.Archs:
if arch not in self.Guids:
self.Guids[arch] = []
self.Guids[arch].append(guid)
# expand protocol
if self._Elements.has_key("Protocols"):
for protocol in self._Elements["Protocols"]:
for arch in protocol.Archs:
if arch not in self.Protocols:
self.Protocols[arch] = []
self.Protocols[arch].append(protocol)
# expand ppi
if self._Elements.has_key("PPIs"):
for ppi in self._Elements["PPIs"]:
for arch in ppi.Archs:
if arch not in self.Ppis:
self.Ppis[arch] = []
self.Ppis[arch].append(ppi)
# expand extern
if self._Elements.has_key("Externs"):
for extern in self._Elements["Externs"]:
for arch in extern.Archs:
if arch not in self.Externs:
self.Externs[arch] = []
self.Externs[arch].append(extern)
def GetLibraryInterface(self, name):
if name in self.Package.LibraryInterfaces:
return self.Package.LibraryInterfaces[name]
for pd in self._Elements["PackageDependencies"]:
if name in pd.Package.LibraryInterfaces:
return pd.Package.LibraryInterfaces[name]
return ""
## def SetupEnvironment(self):
## self.Environment["MODULE"] = self.Name
## self.Environment["MODULE_GUID"] = self.GuidValue
## self.Environment["MODULE_VERSION"] = self.Version
## self.Environment["MODULE_TYPE"] = self.Type
## self.Environment["MODULE_FILE_BASE_NAME"] = os.path.basename(self.Path).split(".")[0]
## self.Environment["MODULE_RELATIVE_DIR"] = os.path.dirname(self.Path)
## self.Environment["BASE_NAME"] = self.OutputName
class Workspace(FrameworkElement.Workspace, SurfaceAreaElement):
_Db = "Tools/Conf/FrameworkDatabase.db"
_Target = "Tools/Conf/Target.txt"
_PlatformBuildPath = "Tools/Conf/platform_build_path.txt"
_ModuleBuildPath = "Tools/Conf/module_build_path.txt"
def __init__(self, path, fpdList=None, msaList=None):
FrameworkElement.Workspace.__init__(self)
SurfaceAreaElement.__init__(self, self, None, None, False, False)
self.Path = os.path.normpath(path)
self.Dir = os.path.dirname(self.Path)
self._Elements["PlatformList"] = fpdList
self._Elements["ModuleList"] = msaList
self.Parse()
self.Postprocess()
def _FdbHeader(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
self.Name = XmlElementData(XmlNode(dom, "/FdbHeader/DatabaseName"))
self.GuidValue = XmlElementData(XmlNode(dom, "/FdbHeader/GuidValue")).upper()
self.Version = XmlElementData(XmlNode(dom, "/FdbHeader/Version"))
def _PackageList(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
fileList = XmlList(dom, "/PackageList/Filename")
packages = []
for f in fileList:
packages.append(os.path.normpath(XmlElementData(f)))
self._Elements["PackageList"] = packages
def _PlatformList(self, xpath):
if len(self._Elements["PlatformList"]) > 0:
return
dom = XmlNode(self._Root, xpath)
if dom == '': return
fileList = XmlList(dom, "/PlatformList/Filename")
platforms = []
for f in fileList:
platforms.append(os.path.normpath(XmlElementData(f)))
self._Elements["PlatformList"] = platforms
def _FarList(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
fileList = XmlList(dom, "/FarList/Filename")
fars = []
for f in fileList:
fars.append(os.path.normpath(XmlElementData(f)))
self._Elements["FarList"] = fars
def ParseWorkspaceDatabase(self):
# parse frameworkdatabase.db
self._Root = xml.dom.minidom.parse(self.SubPath(self._Db))
assert self._Root.documentElement.tagName == "FrameworkDatabase"
self._FdbHeader("/FrameworkDatabase/FdbHeader")
self._PackageList("/FrameworkDatabase/PackageList")
self._PlatformList("/FrameworkDatabase/PlatformList")
self._FarList("/FrameworkDatabase/FarList")
def ParseConfig(self):
# parse target.txt
self.ParseTargetConfig()
# parse tools_def.txt
self.ParseToolConfig()
# parse platform/module_build_path.txt
# active toolchain
# print self.TargetConfig
self.ActiveToolchain = self.TargetConfig["TOOL_CHAIN_TAG"]
if self.ActiveToolchain not in self.ToolConfig.Toolchains:
raise "Not supported tool chain tag %s" % self.ActiveToolchain
# active toolchain family
self.ActiveFamilies = []
for key in self.ToolConfig:
if self.ActiveToolchain in key and "FAMILY" in key:
family = self.ToolConfig[key]
if family not in self.ActiveFamilies:
self.ActiveFamilies.append(family)
def ParsePackage(self, packagePaths=None):
if packagePaths == None:
return
for packagePath in packagePaths:
self.Packages.append(PackageSurfaceArea(self, packagePath))
def ParsePlatform(self, platformPaths=None):
# Only one active platform is allowed
activePlatformPath = ""
if self.TargetConfig["ACTIVE_PLATFORM"] == "":
if platformPaths != None and len(platformPaths) == 1:
activePlatformPath = platformPaths[0]
else:
raise Exception("No active platform specified or implied!")
else:
activePlatformPath = os.path.normpath(self.TargetConfig["ACTIVE_PLATFORM"])
self.ActivePlatform = PlatformSurfaceArea(self, activePlatformPath)
self.Platforms.append(self.ActivePlatform)
def ParseTargetConfig(self):
self.TargetConfig = BuildConfig.TargetConfig(self.SubPath(self._Target))
# print self.TargetConfig
def ParseToolConfig(self):
self.ToolConfig = BuildConfig.ToolConfig(self.SubPath(self.TargetConfig["TOOL_CHAIN_CONF"]))
def GetModule(self, guid, version, packageGuid, packageVersion):
moduleGuidIndex = self.ModuleXref["GUID"]
if guid not in moduleGuidIndex:
print "! No module has GUID=" + guid
return ""
moduleVersionList = moduleGuidIndex[guid]
# print moduleVersionList
moduleList = []
module = ""
if version != "":
if version in moduleVersionList:
moduleList = moduleVersionList[version]
else:
return ""
else:
## no version given, return the first one
version = "0.0"
for ver in moduleVersionList:
if ver > version: version = ver
moduleList = moduleVersionList[version]
if packageGuid == "":
## if no package GUID given, just return the latest one
version = "0.0"
for m in moduleList:
if m.Package.Version > version:
version = m.Package.Version
module = m
else:
version = "0.0"
for m in moduleList:
if m.Package.GuidValue != packageGuid: continue
if packageVersion == "":
## if no version given, just return the latest
if m.Package.Version > version:
version = m.Package.Version
module = m
elif packageVersion == m.Package.Version:
module = m
break;
return module
def GetModuleByPath(self, path):
ownerPackage = ""
ownerPackageFullPath = ""
for package in self.Packages:
ownerPackageFullPath = self.SubPath(package.Path)
if path.startswith(packageFullPath): break
if ownerPackage == "":
return ""
for module in ownerPackage.Modules:
moduleFullPath = os.path.join(ownerPackageFullPath, module.Path)
if moduleFullPath == path:
return module
return ""
def GetPackage(self, guid, version):
packageGuidIndex = self.PackageXref["GUID"]
if guid not in packageGuidIndex:
# raise Exception("No package has GUID=" + guid)
return ""
packageList = packageGuidIndex[guid]
package = ""
if version != "":
if version in packageList:
package = packageList[version]
else:
## no version given, return the latest one
version = "0.0"
for ver in packageList:
if ver > version: version = ver
package = packageList[version]
return package
def GetPlatform(self, guid, version):
pass
def GetPlatformByPath(self, path):
for platform in self.Platforms:
platformFullPath = self.SubPath(platform.Path)
if platformFullPath == path:
return platform
return ""
def GetLibraryInterface(self, name, package):
if name not in self.LibraryInterfaceXref["NAME"]:
return ""
liList = self.LibraryInterfaceXref["NAME"][name]
for li in liList:
if li.Package == package:
return li
return ""
def SubPath(self, *relativePathList):
return os.path.normpath(os.path.join(self.Path, *relativePathList))
def SetupCrossRef(self):
##
## setup platform cross reference as nest-dict
## guid -> {version -> platform}
##
## platformList = self.Platforms
## for p in platformList:
## guid = p.GuidValue
## version = p.Version
## if guid not in self.PlatformIndex:
## self.PlatformIndex[guid] = {}
## if version in self.PlatformIndex[guid]:
## raise Exception("Duplicate platform")
## self.PlatformIndex[guid][version] = p
##
## setup package cross reference as nest-dict
## guid -> {version -> package}
## name -> [package list]
## path -> package
##
packageList = self.Packages
for p in packageList:
guid = p.GuidValue
version = p.Version
packageGuidIndex = self.PackageXref["GUID"]
if guid not in packageGuidIndex:
packageGuidIndex[guid] = {}
if version in packageGuidIndex[guid]:
raise Exception("Duplicate package: %s-%s [%s]" % p.Name, version, guid)
packageGuidIndex[guid][version] = p
packageNameIndex = self.PackageXref["NAME"]
name = p.Name
if name not in packageNameIndex:
packageNameIndex[name] = []
packageNameIndex[name].append(p)
packagePathIndex = self.PackageXref["PATH"]
path = p.Path
if path in packagePathIndex:
raise Exception("Duplicate package: %s %s" % p.Name, p.Path)
packagePathIndex[path] = p.Path
##
## setup library class cross reference as
## library class name -> library class object
##
for lcname in p.LibraryInterfaces:
if lcname not in self.LibraryInterfaceXref["NAME"]:
# raise Exception("Duplicate library class: %s in package %s" % (lcname, name))
self.LibraryInterfaceXref["NAME"][lcname] = []
lcInterface = p.LibraryInterfaces[lcname]
self.LibraryInterfaceXref["NAME"][lcname].append(lcInterface)
lcHeader = p.SubPath(lcInterface.Path)
if lcHeader not in self.LibraryInterfaceXref["PATH"]:
# raise Exception("Duplicate library class interface: %s in package %s" % (lcInterface, name))
self.LibraryInterfaceXref["PATH"][lcHeader] = []
self.LibraryInterfaceXref["PATH"][lcHeader].append(lcInterface)
##
## setup package cross reference as nest-dict
## guid -> {version -> [module list]}
## name -> [module list]
## path -> module
for p in packageList:
p.ParseMsaFile()
moduleList = p.Modules
for m in moduleList:
name = m.Name
path = m.Path
guid = m.GuidValue
version = m.Version
moduleGuidIndex = self.ModuleXref["GUID"]
if guid not in moduleGuidIndex:
moduleGuidIndex[guid] = {}
else:
print "! Duplicate module GUID found:", guid, p.SubPath(path)
dm = moduleGuidIndex[guid].values()[0][0]
print " ", dm.GuidValue,\
dm.Package.SubPath(dm.Path)
if version not in moduleGuidIndex[guid]:
moduleGuidIndex[guid][version] = []
if m in moduleGuidIndex[guid][version]:
raise Exception("Duplicate modules in the same package: %s-%s [%s]" % (name, version, guid))
moduleGuidIndex[guid][version].append(m)
modulePathIndex = self.ModuleXref["PATH"]
path = p.SubPath(m.Path)
if path in modulePathIndex:
raise Exception("Duplicate modules in the same package: %s %s" % (name, path))
modulePathIndex[path] = m
moduleNameIndex = self.ModuleXref["NAME"]
if name not in moduleNameIndex:
moduleNameIndex[name] = []
moduleNameIndex[name].append(m)
def GetToolDef(self, toolchain, target, arch, toolcode, attr):
return self.ToolConfig[(toolchain, target, arch, toolcode, attr)]
def Parse(self):
self.ParseConfig()
self.ParseWorkspaceDatabase()
def SetupBuild(self):
# active archs
self.ActiveArchs = self.TargetConfig["TARGET_ARCH"].split()
if self.ActiveArchs == []:
self.ActiveArchs = self.ActivePlatform.Archs
# active targets
self.ActiveTargets = self.TargetConfig["TARGET"].split()
if self.ActiveTargets == []:
self.ActiveTargets = self.ActivePlatform.Targets
# active modules
for msa in self._Elements["ModuleList"]:
module = self.GetModuleByPath(msa)
if module == "":
raise Exception(msa + " is not in any package!")
self.ActiveModules.append(module)
self.IndividualModuleBuild = True
if self.TargetConfig["MULTIPLE_THREAD"].upper() == "ENABLE":
self.MultiThreadBuild = True
if "MAX_CONCURRENT_THREAD_NUMBER" in self.TargetConfig:
self.ThreadCount = self.TargetConfig["MAX_CONCURRENT_THREAD_NUMBER"]
else:
self.ThreadCount = "1"
def Postprocess(self):
self.ParsePackage(self._Elements["PackageList"])
self.SetupCrossRef()
self.ParsePlatform(self._Elements["PlatformList"])
self.SetupBuild()
## def SetupEnvironment(self):
## config = BuildConfig.Config(self.SubPath(self._PlatformBuildPath))
## for name in config:
## self.Environment[name] = config[name]
##
## config = BuildConfig.Config(self.SubPath(self._ModuleBuildPath))
## for name in config:
## self.Environment[name] = config[name]
##
## multiThread = self.TargetConfig["MULTIPLE_THREAD"].upper()
## threadNumber = self.TargetConfig["MAX_CONCURRENT_THREAD_NUMBER"]
## if multiThread == "" or multiThread == "FALSE":
## self.Environment["MULTIPLE_THREAD"] = False
## self.Environment["MAX_CONCURRENT_THREAD_NUMBER"] = 1
## else:
## self.Environment["MULTIPLE_THREAD"] = True
## if threadNumber != "":
## self.Environment["MAX_CONCURRENT_THREAD_NUMBER"] = threadNumber
## else:
## self.Environment["MAX_CONCURRENT_THREAD_NUMBER"] = 2
class PackageSurfaceArea(FrameworkElement.Package, SurfaceAreaElement):
def __init__(self, workspace, path):
FrameworkElement.Package.__init__(self)
self.Path = os.path.normpath(path)
self.Dir = os.path.dirname(self.Path)
SurfaceAreaElement.__init__(self, workspace, workspace, None, True, True)
def _SpdHeader(self, xpath):
dom = XmlNode(self._Root, xpath)
self.Name = XmlElementData(XmlNode(dom, "/SpdHeader/PackageName"))
self.GuidValue = XmlElementData(XmlNode(dom, "/SpdHeader/GuidValue")).upper()
self.Version = XmlElementData(XmlNode(dom, "/SpdHeader/Version"))
def _PackageDefinitions(self, xpath):
dom = XmlNode(self._Root, xpath)
self.ReadOnly = XmlElementData(XmlNode(dom, "/PackageDefinitions/ReadOnly"))
self.Repackage = XmlElementData(XmlNode(dom, "/PackageDefinitions/RePackage"))
def _LibraryClassDeclarations(self, xpath):
dom = XmlNode(self._Root, xpath)
lcdList = XmlList(dom, "/LibraryClassDeclarations/LibraryClass")
lcds = []
for lc in lcdList:
lcds.append(LibraryDeclaration(self._Workspace, self, lc))
self._Elements["LibraryClassDeclarations"] = lcds
def _IndustryStdIncludes(self, xpath):
dom = XmlNode(self._Root, xpath)
headerList = XmlList(dom, "/IndustryStdIncludes/IndustryStdHeader")
headers = []
for h in headerList:
headers.append(IndustryStdHeader(self._Workspace, self, h))
self._Elements["IndustryStdIncludes"] = headers
def _MsaFiles(self, xpath):
dom = XmlNode(self._Root, xpath)
msaFileList = XmlList(dom, "/MsaFiles/Filename")
msaFiles = []
for msa in msaFileList:
filePath = os.path.normpath(XmlElementData(msa))
msaFiles.append(filePath)
self._Elements["MsaFiles"] = msaFiles
def _PackageHeaders(self, xpath):
dom = XmlNode(self._Root, xpath)
headerList = XmlList(dom, "/PackageHeaders/IncludePkgHeader")
headers = []
for h in headerList:
headers.append(PackageHeader(self._Workspace, self, h))
self._Elements["PackageHeaders"] = headers
def _GuidDeclarations(self, xpath):
dom = XmlNode(self._Root, xpath)
guidList = XmlList(dom, "/GuidDeclarations/Entry")
guids = []
for guid in guidList:
guids.append(GuidDeclaration(self._Workspace, self, guid))
self._Elements["GuidDeclarations"] = guids
def _ProtocolDeclarations(self, xpath):
dom = XmlNode(self._Root, xpath)
protocolList = XmlList(dom, "/ProtocolDeclarations/Entry")
protocols = []
for p in protocolList:
protocols.append(ProtocolDeclaration(self._Workspace, self, p))
self._Elements["ProtocolDeclarations"] = protocols
def _PpiDeclarations(self, xpath):
dom = XmlNode(self._Root, xpath)
ppiList = XmlList(dom, "/PpiDeclarations/Entry")
ppis = []
for p in ppiList:
ppis.append(PpiDeclaration(self._Workspace, self, p))
self._Elements["PpiDeclarations"] = ppis
def _PcdDeclarations(self, xpath):
dom = XmlNode(self._Root, xpath)
pcdList = XmlList(dom, "/PcdDeclarations/PcdEntry")
pcds = []
for p in pcdList:
pcds.append(PcdDeclaration(self._Workspace, self, p))
self._Elements["PcdDeclarations"] = pcds
def SubPath(self, *relativePathList):
return os.path.normpath(os.path.join(self.Dir, *relativePathList))
def Parse(self):
self._Root = xml.dom.minidom.parse(self._Workspace.SubPath(self.Path))
assert self._Root.documentElement.tagName == "PackageSurfaceArea"
# print "Parsing...",self.Path
self._SpdHeader("/PackageSurfaceArea/SpdHeader")
self._PackageDefinitions("/PackageSurfaceArea/PackageDefinitions")
self._LibraryClassDeclarations("/PackageSurfaceArea/LibraryClassDeclarations")
self._IndustryStdIncludes("/PackageSurfaceArea/IndustryStdIncludes")
self._MsaFiles("/PackageSurfaceArea/MsaFiles")
self._PackageHeaders("/PackageSurfaceArea/PackageHeaders")
self._GuidDeclarations("/PackageSurfaceArea/GuidDeclarations")
self._ProtocolDeclarations("/PackageSurfaceArea/ProtocolDeclarations")
self._PpiDeclarations("/PackageSurfaceArea/PpiDeclarations")
self._PcdDeclarations("/PackageSurfaceArea/PcdDeclarations")
def Postprocess(self):
# setup guid, protocol, ppi
for guid in self._Elements["GuidDeclarations"]:
if guid.CName in self.Guids:
print "! Duplicate GUID CName (%s) in package %s" % (guid.CName, self.Path)
self.Guids[guid.CName] = guid
for protocol in self._Elements["ProtocolDeclarations"]:
if protocol.CName in self.Protocols:
print "! Duplicate Protocol CName (%s) in package %s" % (protocol.CName, self.Path)
self.Protocols[protocol.CName] = protocol
for ppi in self._Elements["PpiDeclarations"]:
if ppi.CName in self.Ppis:
print "! Duplicate PPI CName (%s) in package (%s)" % (ppi.CName, self.Path)
self.Ppis[ppi.CName] = ppi
# package header
for inc in self._Elements["PackageHeaders"]:
if inc.ModuleType not in self.PackageIncludes:
self.PackageIncludes[inc.ModuleType] = []
self.PackageIncludes[inc.ModuleType].append(inc.Path)
# library class
for lcd in self._Elements["LibraryClassDeclarations"]:
if lcd.Name in self.LibraryInterfaces:
raise "Duplicate library class: " + lcd.Name
self.LibraryInterfaces[lcd.Name] = lcd
# parse mas files
# self.ParseMsaFile()
# resolve RecommendedInstance
def ParseMsaFile(self):
for msaFilePath in self._Elements["MsaFiles"]:
self.Modules.append(ModuleSurfaceArea(self._Workspace, self, msaFilePath))
class PlatformSurfaceArea(FrameworkElement.Platform, SurfaceAreaElement):
def __init__(self, workspace, path):
FrameworkElement.Platform.__init__(self)
self.Path = os.path.normpath(path)
self.Dir = os.path.dirname(self.Path)
SurfaceAreaElement.__init__(self, workspace)
def _PlatformHeader(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
self.Name = XmlElementData(XmlNode(dom, "/PlatformHeader/PlatformName"))
self.GuidValue = XmlElementData(XmlNode(dom, "/PlatformHeader/GuidValue")).upper()
self.Version = XmlElementData(XmlNode(dom, "/PlatformHeader/Version"))
def _PlatformDefinitions(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
self.Archs = XmlElementData(XmlNode(dom, "/PlatformDefinitions/SupportedArchitectures")).split()
if self.Archs == []:
raise Exception("No ARCH specified in platform " + self.Path)
self.Targets = XmlElementData(XmlNode(dom, "/PlatformDefinitions/BuildTargets")).split()
self.OutputPath = os.path.normpath(XmlElementData(XmlNode(dom, "/PlatformDefinitions/OutputDirectory")))
def _Flash(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
def _FrameworkModules(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
moduleList = XmlList(dom, "/FrameworkModules/ModuleSA")
modules = []
for m in moduleList:
modules.append(PlatformModule(self._Workspace, self, m))
self._Elements["FrameworkModules"] = modules
def _DynamicPcdBuildDefinitions(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
def _BuildOptions(self, xpath):
dom = XmlNode(self._Root, xpath)
if dom == '': return
self.BuildOptions = self.GetBuildOptionList(XmlNode(dom, "/BuildOptions/Options"))
# print self.BuildOptions
def _UserExtensions(self, xpath):
domList = XmlList(self._Root, xpath)
if domList == []: return
for extension in domList:
userId = XmlAttribute(extension, "UserID")
identifier = XmlAttribute(extension, "Identifier")
if userId == '' or identifier == '':
raise Exception("No UserId or Identifier specified")
if userId != "TianoCore": continue
if identifier not in self.UserExtensions:
self.UserExtensions[identifier] = []
contentList = self.UserExtensions[identifier]
for node in extension.childNodes:
# print node.nodeType
contentList.append(node.cloneNode(True))
def Parse(self):
self._Root = xml.dom.minidom.parse(self._Workspace.SubPath(self.Path))
assert self._Root.documentElement.tagName == "PlatformSurfaceArea"
self._PlatformHeader("/PlatformSurfaceArea/PlatformHeader")
self._PlatformDefinitions("/PlatformSurfaceArea/PlatformDefinitions")
self._Flash("/PlatformSurfaceArea/Flash")
self._FrameworkModules("/PlatformSurfaceArea/FrameworkModules")
self._DynamicPcdBuildDefinitions("/PlatformSurfaceArea/DynamicPcdBuildDefinitions")
self._BuildOptions("/PlatformSurfaceArea/BuildOptions")
self._UserExtensions("/PlatformSurfaceArea/UserExtensions")
def Postprocess(self):
# summarize all library modules for build
for module in self._Elements["FrameworkModules"]:
for arch in module.Archs:
if arch not in self.Modules:
self.Modules[arch] = []
self.Modules[arch].append(module)
if arch not in self.Libraries:
self.Libraries[arch] = []
for li in module.Libraries:
if li in self.Libraries[arch]: continue
self.Libraries[arch].append(li)
# FV
for fvName in module.FvBindings:
if fvName not in self.Fvs:
self.Fvs[fvName] = []
self.Fvs[fvName].append(module)
# build options
# user extension
## def SetupEnvironment(self):
## self.Environment["PLATFORM"] = self.Name
## self.Environment["PLATFORM_GUID"] = self.GuidValue
## self.Environment["PLATFORM_VERSION"] = self.Version
## self.Environment["PLATFORM_RELATIVE_DIR"] = self.Path
## self.Environment["PLATFORM_OUTPUT_DIR"] = self.OutputPath
def PrintWorkspace(ws):
print "\nPlatforms:\n"
for guid in ws.PlatformXref["GUID"]:
for ver in ws.PlatformXref["GUID"][guid]:
platform = ws.PlatformXref["GUID"][guid][ver]
print " %s %s-%s" % (guid, platform.Name, ver)
for pm in platform.Modules:
print " %-40s %-10s <%s-%s>" % (pm.Module.Name+"-"+pm.Module.Version,
ListString(pm.Archs), pm.Module.Package.Name,
pm.Module.Package.Version)
for li in pm.Libraries:
print " %-47s <%s-%s>" % (li.Module.Name+"-"+li.Module.Version,
li.Module.Package.Name, li.Module.Package.Version)
print ""
print "\nPackages:\n"
for guid in ws.PackageXref["GUID"]:
for ver in ws.PackageXref["GUID"][guid]:
print " %s %s-%s" % (guid, ws.PackageXref["GUID"][guid][ver].Name, ver)
print "\nModules:\n"
for guid in ws.ModuleXref["GUID"]:
for ver in ws.ModuleXref["GUID"][guid]:
for module in ws.ModuleXref["GUID"][guid][ver]:
print " %s %-40s [%s-%s]" % (guid, module.Name+"-"+ver, module.Package.Name, module.Package.Version)
print " Depending on packages:"
for arch in module.IncludePaths:
print " ", arch, ":"
for path in module.IncludePaths[arch]:
print " ", path
print "\n"
for arch in module.IncludeFiles:
print " ", arch, ":"
for path in module.IncludeFiles[arch]:
print " ", path
print "\n"
print " Source files:"
for arch in module.SourceFiles:
print " ", arch, ":"
for type in module.SourceFiles[arch]:
for src in module.SourceFiles[arch][type]:
print " %-40s (%s)" % (src.Path, src.Type)
print "\n"
print "\nLibrary Classes:"
for name in ws.LibraryInterfaceXref["NAME"]:
lcList = ws.LibraryInterfaceXref["NAME"][name]
for lc in lcList:
pkgPath = os.path.dirname(lc.Package.Path)
print "\n [%s] <%s>" % (lc.Name, pkgPath + os.path.sep + lc.Path)
print " Produced By:"
for li in lc.Instances:
print " %-40s <%s>" % (li.Name+"-"+li.Version, li.Package.SubPath(li.Path))
print " Consumed By:"
for li in lc.Consumers:
print " %-40s <%s>" % (li.Name+"-"+li.Version, li.Package.SubPath(li.Path))
print "\nActive Platform:"
for arch in ws.ActivePlatform.Libraries:
print " Library Instances (%s) (%d libraries)" % (arch , len(ws.ActivePlatform.Libraries[arch]))
for li in ws.ActivePlatform.Libraries[arch]:
print " %s-%s (%s-%s)" % (li.Module.Name, li.Module.Version,
li.Module.Package.Name, li.Module.Package.Version)
for arch in ws.ActivePlatform.Modules:
print " Driver Modules (%s) (%d modules)" % (arch, len(ws.ActivePlatform.Modules[arch]))
for m in ws.ActivePlatform.Modules[arch]:
print " %s-%s (%s-%s)" % (m.Module.Name, m.Module.Version,
m.Module.Package.Name, m.Module.Package.Version)
for fv in ws.ActivePlatform.Fvs:
print
print " Firmware Volume (%s) (%d modules)" % (fv, len(ws.ActivePlatform.Fvs[fv]))
for m in ws.ActivePlatform.Fvs[fv]:
print " %s-%s (%s-%s)" % (m.Module.Name, m.Module.Version,
m.Module.Package.Name, m.Module.Package.Version)
# for test
if __name__ == "__main__":
# os.environ["WORKSPACE"]
workspacePath = os.getenv("WORKSPACE", os.getcwd())
saFile = ""
if len(sys.argv) <= 1:
saFile = os.path.join(workspacePath, "Tools/Conf/FrameworkDatabase.db")
else:
saFile = sys.argv[1]
print "Parsing ... %s\n" % saFile
startTime = time.clock()
sa = Workspace(workspacePath, [], [])
# sa = PackageSurfaceArea(saFile)
# sa = PlatformSurfaceArea(saFile)
# sa = ModuleSurfaceArea(saFile)
# print sa
PrintWorkspace(sa)
print "\n[Finished in %fs]" % (time.clock() - startTime)