| #!/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)
|
|
|