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