summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py')
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py928
1 files changed, 928 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py
new file mode 100755
index 00000000..0bafe2dc
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py
@@ -0,0 +1,928 @@
+## @file
+#
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+from plugins.EdkPlugins.basemodel import ini
+from plugins.EdkPlugins.edk2.model import dsc
+from plugins.EdkPlugins.edk2.model import inf
+from plugins.EdkPlugins.edk2.model import dec
+import os
+from plugins.EdkPlugins.basemodel.message import *
+
+class SurfaceObject(object):
+ _objs = {}
+
+ def __new__(cls, *args, **kwargs):
+ """Maintain only a single instance of this object
+ @return: instance of this class
+
+ """
+ obj = object.__new__(cls)
+ if "None" not in cls._objs:
+ cls._objs["None"] = []
+ cls._objs["None"].append(obj)
+
+ return obj
+
+ def __init__(self, parent, workspace):
+ self._parent = parent
+ self._fileObj = None
+ self._workspace = workspace
+ self._isModify = False
+ self._modifiedObjs = []
+
+ def __del__(self):
+ pass
+
+ def Destroy(self):
+ key = self.GetRelativeFilename()
+ self.GetFileObj().Destroy(self)
+ del self._fileObj
+ # dereference self from _objs arrary
+ assert key in self._objs, "when destory, object is not in obj list"
+ assert self in self._objs[key], "when destory, object is not in obj list"
+ self._objs[key].remove(self)
+ if len(self._objs[key]) == 0:
+ del self._objs[key]
+
+ def GetParent(self):
+ return self._parent
+
+ def GetWorkspace(self):
+ return self._workspace
+
+ def GetFileObjectClass(self):
+ return ini.BaseINIFile
+
+ def GetFilename(self):
+ return self.GetFileObj().GetFilename()
+
+ def GetFileObj(self):
+ return self._fileObj
+
+ def GetRelativeFilename(self):
+ fullPath = self.GetFilename()
+ return fullPath[len(self._workspace) + 1:]
+
+ def Load(self, relativePath):
+ # if has been loaded, directly return
+ if self._fileObj is not None: return True
+
+ relativePath = os.path.normpath(relativePath)
+ fullPath = os.path.join(self._workspace, relativePath)
+ fullPath = os.path.normpath(fullPath)
+
+ if not os.path.exists(fullPath):
+ ErrorMsg("file does not exist!", fullPath)
+ return False
+
+ self._fileObj = self.GetFileObjectClass()(fullPath, self)
+
+ if not self._fileObj.Parse():
+ ErrorMsg("Fail to parse file!", fullPath)
+ return False
+
+ # remove self from None list to list with filename as key
+ cls = self.__class__
+ if self not in cls._objs["None"]:
+ ErrorMsg("Sufrace object does not be create into None list")
+ cls._objs["None"].remove(self)
+ if relativePath not in cls._objs:
+ cls._objs[relativePath] = []
+ cls._objs[relativePath].append(self)
+
+ return True
+
+ def Reload(self, force=False):
+ ret = True
+ # whether require must be update
+ if force:
+ ret = self.GetFileObj().Reload(True)
+ else:
+ if self.IsModified():
+ if self.GetFileObj().IsModified():
+ ret = self.GetFileObj().Reload()
+ return ret
+
+ def Modify(self, modify=True, modifiedObj=None):
+ if modify:
+ #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))
+ if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:
+ return
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+ else:
+ self._isModify = modify
+
+ def IsModified(self):
+ return self._isModify
+
+ def GetModifiedObjs(self):
+ return self._modifiedObjs
+
+ def FilterObjsByArch(self, objs, arch):
+ arr = []
+ for obj in objs:
+ if obj.GetArch().lower() == 'common':
+ arr.append(obj)
+ continue
+ if obj.GetArch().lower() == arch.lower():
+ arr.append(obj)
+ continue
+ return arr
+
+class Platform(SurfaceObject):
+ def __init__(self, parent, workspace):
+ SurfaceObject.__init__(self, parent, workspace)
+ self._modules = []
+ self._packages = []
+
+ def Destroy(self):
+ for module in self._modules:
+ module.Destroy()
+ del self._modules[:]
+
+ del self._packages[:]
+ SurfaceObject.Destroy(self)
+
+ def GetName(self):
+ return self.GetFileObj().GetDefine("PLATFORM_NAME")
+
+ def GetFileObjectClass(self):
+ return dsc.DSCFile
+
+ def GetModuleCount(self):
+ if self.GetFileObj() is None:
+ ErrorMsg("Fail to get module count because DSC file has not been load!")
+
+ return len(self.GetFileObj().GetComponents())
+
+ def GetSupportArchs(self):
+ return self.GetFileObj().GetDefine("SUPPORTED_ARCHITECTURES").strip().split('#')[0].split('|')
+
+ def LoadModules(self, precallback=None, postcallback=None):
+ for obj in self.GetFileObj().GetComponents():
+ mFilename = obj.GetFilename()
+ if precallback is not None:
+ precallback(self, mFilename)
+ arch = obj.GetArch()
+ if arch.lower() == 'common':
+ archarr = self.GetSupportArchs()
+ else:
+ archarr = [arch]
+ for arch in archarr:
+ module = Module(self, self.GetWorkspace())
+ if module.Load(mFilename, arch, obj.GetOveridePcds(), obj.GetOverideLibs()):
+ self._modules.append(module)
+ if postcallback is not None:
+ postcallback(self, module)
+ else:
+ del module
+ ErrorMsg("Fail to load module %s" % mFilename)
+
+ def GetModules(self):
+ return self._modules
+
+ def GetLibraryPath(self, classname, arch, type):
+ objs = self.GetFileObj().GetSectionObjectsByName("libraryclasses")
+
+ for obj in objs:
+ if classname.lower() != obj.GetClass().lower():
+ continue
+ if obj.GetArch().lower() != 'common' and \
+ obj.GetArch().lower() != arch.lower():
+ continue
+
+ if obj.GetModuleType().lower() != 'common' and \
+ obj.GetModuleType().lower() != type.lower():
+ continue
+
+ return obj.GetInstance()
+
+ ErrorMsg("Fail to get library class %s [%s][%s] from platform %s" % (classname, arch, type, self.GetFilename()))
+ return None
+
+ def GetPackage(self, path):
+ package = self.GetParent().GetPackage(path)
+ if package not in self._packages:
+ self._packages.append(package)
+ return package
+
+ def GetPcdBuildObjs(self, name, arch=None):
+ arr = []
+ objs = self.GetFileObj().GetSectionObjectsByName('pcds')
+ for obj in objs:
+ if obj.GetPcdName().lower() == name.lower():
+ arr.append(obj)
+ if arch is not None:
+ arr = self.FilterObjsByArch(arr, arch)
+ return arr
+
+ def Reload(self, callback=None):
+ # do not care force paramter for platform object
+ isFileChanged = self.GetFileObj().IsModified()
+ ret = SurfaceObject.Reload(self, False)
+ if not ret: return False
+ if isFileChanged:
+ # destroy all modules and reload them again
+ for obj in self._modules:
+ obj.Destroy()
+ del self._modules[:]
+ del self._packages[:]
+ self.LoadModules(callback)
+ else:
+ for obj in self._modules:
+ callback(self, obj.GetFilename())
+ obj.Reload()
+
+ self.Modify(False)
+ return True
+
+ def Modify(self, modify=True, modifiedObj=None):
+ if modify:
+ #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))
+ if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:
+ return
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+ else:
+ if self.GetFileObj().IsModified():
+ return
+ for obj in self._modules:
+ if obj.IsModified():
+ return
+
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+
+ def GetModuleObject(self, relativePath, arch):
+ path = os.path.normpath(relativePath)
+ for obj in self._modules:
+ if obj.GetRelativeFilename() == path:
+ if arch.lower() == 'common':
+ return obj
+ if obj.GetArch() == arch:
+ return obj
+ return None
+
+ def GenerateFullReferenceDsc(self):
+ oldDsc = self.GetFileObj()
+ newDsc = dsc.DSCFile()
+ newDsc.CopySectionsByName(oldDsc, 'defines')
+ newDsc.CopySectionsByName(oldDsc, 'SkuIds')
+
+ #
+ # Dynamic common section should also be copied
+ #
+ newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicDefault')
+ newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicHii')
+ newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicVpd')
+ newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicEx')
+
+ sects = oldDsc.GetSectionByName('Components')
+ for oldSect in sects:
+ newSect = newDsc.AddNewSection(oldSect.GetName())
+ for oldComObj in oldSect.GetObjects():
+ module = self.GetModuleObject(oldComObj.GetFilename(), oldSect.GetArch())
+ if module is None: continue
+
+ newComObj = dsc.DSCComponentObject(newSect)
+ newComObj.SetFilename(oldComObj.GetFilename())
+
+ # add all library instance for override section
+ libdict = module.GetLibraries()
+ for libclass in libdict.keys():
+ if libdict[libclass] is not None:
+ newComObj.AddOverideLib(libclass, libdict[libclass].GetRelativeFilename().replace('\\', '/'))
+
+ # add all pcds for override section
+ pcddict = module.GetPcds()
+ for pcd in pcddict.values():
+ buildPcd = pcd.GetBuildObj()
+ buildType = buildPcd.GetPcdType()
+ buildValue = None
+ if buildType.lower() == 'pcdsdynamichii' or \
+ buildType.lower() == 'pcdsdynamicvpd' or \
+ buildType.lower() == 'pcdsdynamicdefault':
+ buildType = 'PcdsDynamic'
+ if buildType != 'PcdsDynamic':
+ buildValue = buildPcd.GetPcdValue()
+ newComObj.AddOveridePcd(buildPcd.GetPcdName(),
+ buildType,
+ buildValue)
+ newSect.AddObject(newComObj)
+ return newDsc
+
+class Module(SurfaceObject):
+ def __init__(self, parent, workspace):
+ SurfaceObject.__init__(self, parent, workspace)
+ self._arch = 'common'
+ self._parent = parent
+ self._overidePcds = {}
+ self._overideLibs = {}
+ self._libs = {}
+ self._pcds = {}
+ self._ppis = []
+ self._protocols = []
+ self._depexs = []
+ self._guids = []
+ self._packages = []
+
+ def Destroy(self):
+ for lib in self._libs.values():
+ if lib is not None:
+ lib.Destroy()
+ self._libs.clear()
+
+ for pcd in self._pcds.values():
+ pcd.Destroy()
+ self._pcds.clear()
+
+ for ppi in self._ppis:
+ ppi.DeRef(self)
+ del self._ppis[:]
+
+ for protocol in self._protocols:
+ if protocol is not None:
+ protocol.DeRef(self)
+ del self._protocols[:]
+
+ for guid in self._guids:
+ if guid is not None:
+ guid.DeRef(self)
+ del self._guids[:]
+
+ del self._packages[:]
+ del self._depexs[:]
+ SurfaceObject.Destroy(self)
+
+ def GetFileObjectClass(self):
+ return inf.INFFile
+
+ def GetLibraries(self):
+ return self._libs
+
+ def Load(self, filename, arch='common', overidePcds=None, overideLibs=None):
+ if not SurfaceObject.Load(self, filename):
+ return False
+
+ self._arch = arch
+ if overidePcds is not None:
+ self._overideLibs = overideLibs
+ if overideLibs is not None:
+ self._overidePcds = overidePcds
+
+ self._SearchLibraries()
+ self._SearchPackage()
+ self._SearchSurfaceItems()
+ return True
+
+ def GetArch(self):
+ return self._arch
+
+ def GetModuleName(self):
+ return self.GetFileObj().GetDefine("BASE_NAME")
+
+ def GetModuleType(self):
+ return self.GetFileObj().GetDefine("MODULE_TYPE")
+
+ def GetPlatform(self):
+ return self.GetParent()
+
+ def GetModuleObj(self):
+ return self
+
+ def GetPcds(self):
+ pcds = self._pcds.copy()
+ for lib in self._libs.values():
+ if lib is None: continue
+ for name in lib._pcds.keys():
+ pcds[name] = lib._pcds[name]
+ return pcds
+
+ def GetPpis(self):
+ ppis = []
+ ppis += self._ppis
+ for lib in self._libs.values():
+ if lib is None: continue
+ ppis += lib._ppis
+ return ppis
+
+ def GetProtocols(self):
+ pros = []
+ pros = self._protocols
+ for lib in self._libs.values():
+ if lib is None: continue
+ pros += lib._protocols
+ return pros
+
+ def GetGuids(self):
+ guids = []
+ guids += self._guids
+ for lib in self._libs.values():
+ if lib is None: continue
+ guids += lib._guids
+ return guids
+
+ def GetDepexs(self):
+ deps = []
+ deps += self._depexs
+ for lib in self._libs.values():
+ if lib is None: continue
+ deps += lib._depexs
+ return deps
+
+ def IsLibrary(self):
+ return self.GetFileObj().GetDefine("LIBRARY_CLASS") is not None
+
+ def GetLibraryInstance(self, classname, arch, type):
+ if classname not in self._libs.keys():
+ # find in overide lib firstly
+ if classname in self._overideLibs.keys():
+ self._libs[classname] = Library(self, self.GetWorkspace())
+ self._libs[classname].Load(self._overideLibs[classname])
+ return self._libs[classname]
+
+ parent = self.GetParent()
+ if issubclass(parent.__class__, Platform):
+ path = parent.GetLibraryPath(classname, arch, type)
+ if path is None:
+ ErrorMsg('Fail to get library instance for %s' % classname, self.GetFilename())
+ return None
+ self._libs[classname] = Library(self, self.GetWorkspace())
+ if not self._libs[classname].Load(path, self.GetArch()):
+ self._libs[classname] = None
+ else:
+ self._libs[classname] = parent.GetLibraryInstance(classname, arch, type)
+ return self._libs[classname]
+
+ def GetSourceObjs(self):
+ return self.GetFileObj().GetSectionObjectsByName('source')
+
+ def _SearchLibraries(self):
+ objs = self.GetFileObj().GetSectionObjectsByName('libraryclasses')
+ arch = self.GetArch()
+ type = self.GetModuleType()
+ for obj in objs:
+ if obj.GetArch().lower() != 'common' and \
+ obj.GetArch().lower() not in self.GetPlatform().GetSupportArchs():
+ continue
+ classname = obj.GetClass()
+ instance = self.GetLibraryInstance(classname, arch, type)
+ if not self.IsLibrary() and instance is not None:
+ instance._isInherit = False
+
+ if classname not in self._libs.keys():
+ self._libs[classname] = instance
+
+ def _SearchSurfaceItems(self):
+ # get surface item from self's inf
+ pcds = []
+ ppis = []
+ pros = []
+ deps = []
+ guids = []
+ if self.GetFileObj() is not None:
+ pcds = self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('pcd'),
+ self.GetArch())
+ for pcd in pcds:
+ if pcd.GetPcdName() not in self._pcds.keys():
+ pcdItem = PcdItem(pcd.GetPcdName(), self, pcd)
+ self._pcds[pcd.GetPcdName()] = ModulePcd(self,
+ pcd.GetPcdName(),
+ pcd,
+ pcdItem)
+
+ ppis += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('ppis'),
+ self.GetArch())
+
+ for ppi in ppis:
+ item = PpiItem(ppi.GetName(), self, ppi)
+ if item not in self._ppis:
+ self._ppis.append(item)
+
+ pros += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('protocols'),
+ self.GetArch())
+
+ for pro in pros:
+ item = ProtocolItem(pro.GetName(), self, pro)
+ if item not in self._protocols:
+ self._protocols.append(item)
+
+ deps += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('depex'),
+ self.GetArch())
+ for dep in deps:
+ item = DepexItem(self, dep)
+ self._depexs.append(item)
+
+ guids += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('guids'),
+ self.GetArch())
+ for guid in guids:
+ item = GuidItem(guid.GetName(), self, guid)
+ if item not in self._guids:
+ self._guids.append(item)
+
+ def _SearchPackage(self):
+ objs = self.GetFileObj().GetSectionObjectsByName('packages')
+ for obj in objs:
+ package = self.GetPlatform().GetPackage(obj.GetPath())
+ if package is not None:
+ self._packages.append(package)
+
+ def GetPackages(self):
+ return self._packages
+
+ def GetPcdObjects(self):
+ if self.GetFileObj() is None:
+ return []
+
+ return self.GetFileObj().GetSectionObjectsByName('pcd')
+
+ def GetLibraryClassHeaderFilePath(self):
+ lcname = self.GetFileObj().GetProduceLibraryClass()
+ if lcname is None: return None
+
+ pkgs = self.GetPackages()
+ for package in pkgs:
+ path = package.GetLibraryClassHeaderPathByName(lcname)
+ if path is not None:
+ return os.path.realpath(os.path.join(package.GetFileObj().GetPackageRootPath(), path))
+ return None
+
+ def Reload(self, force=False, callback=None):
+ if callback is not None:
+ callback(self, "Starting reload...")
+
+ ret = SurfaceObject.Reload(self, force)
+ if not ret: return False
+
+ if not force and not self.IsModified():
+ return True
+
+ for lib in self._libs.values():
+ if lib is not None:
+ lib.Destroy()
+ self._libs.clear()
+
+ for pcd in self._pcds.values():
+ pcd.Destroy()
+ self._pcds.clear()
+
+ for ppi in self._ppis:
+ ppi.DeRef(self)
+ del self._ppis[:]
+
+ for protocol in self._protocols:
+ protocol.DeRef(self)
+ del self._protocols[:]
+
+ for guid in self._guids:
+ guid.DeRef(self)
+ del self._guids[:]
+
+ del self._packages[:]
+ del self._depexs[:]
+
+ if callback is not None:
+ callback(self, "Searching libraries...")
+ self._SearchLibraries()
+ if callback is not None:
+ callback(self, "Searching packages...")
+ self._SearchPackage()
+ if callback is not None:
+ callback(self, "Searching surface items...")
+ self._SearchSurfaceItems()
+
+ self.Modify(False)
+ return True
+
+ def Modify(self, modify=True, modifiedObj=None):
+ if modify:
+ #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))
+ if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:
+ return
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+ else:
+ if self.GetFileObj().IsModified():
+ return
+
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+
+class Library(Module):
+ def __init__(self, parent, workspace):
+ Module.__init__(self, parent, workspace)
+ self._isInherit = True
+
+ def IsInherit(self):
+ return self._isInherit
+
+ def GetModuleType(self):
+ return self.GetParent().GetModuleType()
+
+ def GetPlatform(self):
+ return self.GetParent().GetParent()
+
+ def GetModuleObj(self):
+ return self.GetParent()
+
+ def GetArch(self):
+ return self.GetParent().GetArch()
+
+ def Destroy(self):
+ self._libs.clear()
+ self._pcds.clear()
+ SurfaceObject.Destroy(self)
+
+class Package(SurfaceObject):
+ def __init__(self, parent, workspace):
+ SurfaceObject.__init__(self, parent, workspace)
+ self._pcds = {}
+ self._guids = {}
+ self._protocols = {}
+ self._ppis = {}
+
+ def GetPcds(self):
+ return self._pcds
+
+ def GetPpis(self):
+ return list(self._ppis.values())
+
+ def GetProtocols(self):
+ return list(self._protocols.values())
+
+ def GetGuids(self):
+ return list(self._guids.values())
+
+ def Destroy(self):
+ for pcd in self._pcds.values():
+ if pcd is not None:
+ pcd.Destroy()
+ for guid in self._guids.values():
+ if guid is not None:
+ guid.Destroy()
+ for protocol in self._protocols.values():
+ if protocol is not None:
+ protocol.Destroy()
+ for ppi in self._ppis.values():
+ if ppi is not None:
+ ppi.Destroy()
+ self._pcds.clear()
+ self._guids.clear()
+ self._protocols.clear()
+ self._ppis.clear()
+ self._pcds.clear()
+ SurfaceObject.Destroy(self)
+
+ def Load(self, relativePath):
+ ret = SurfaceObject.Load(self, relativePath)
+ if not ret: return False
+ pcds = self.GetFileObj().GetSectionObjectsByName('pcds')
+ for pcd in pcds:
+ if pcd.GetPcdName() in self._pcds.keys():
+ if self._pcds[pcd.GetPcdName()] is not None:
+ self._pcds[pcd.GetPcdName()].AddDecObj(pcd)
+ else:
+ self._pcds[pcd.GetPcdName()] = PcdItem(pcd.GetPcdName(), self, pcd)
+
+ guids = self.GetFileObj().GetSectionObjectsByName('guids')
+ for guid in guids:
+ if guid.GetName() not in self._guids.keys():
+ self._guids[guid.GetName()] = GuidItem(guid.GetName(), self, guid)
+ else:
+ WarnMsg("Duplicate definition for %s" % guid.GetName())
+
+ ppis = self.GetFileObj().GetSectionObjectsByName('ppis')
+ for ppi in ppis:
+ if ppi.GetName() not in self._ppis.keys():
+ self._ppis[ppi.GetName()] = PpiItem(ppi.GetName(), self, ppi)
+ else:
+ WarnMsg("Duplicate definition for %s" % ppi.GetName())
+
+ protocols = self.GetFileObj().GetSectionObjectsByName('protocols')
+ for protocol in protocols:
+ if protocol.GetName() not in self._protocols.keys():
+ self._protocols[protocol.GetName()] = ProtocolItem(protocol.GetName(), self, protocol)
+ else:
+ WarnMsg("Duplicate definition for %s" % protocol.GetName())
+
+ return True
+
+ def GetFileObjectClass(self):
+ return dec.DECFile
+
+ def GetName(self):
+ return self.GetFileObj().GetDefine("PACKAGE_NAME")
+
+ def GetPcdDefineObjs(self, name=None):
+ arr = []
+ objs = self.GetFileObj().GetSectionObjectsByName('pcds')
+ if name is None: return objs
+
+ for obj in objs:
+ if obj.GetPcdName().lower() == name.lower():
+ arr.append(obj)
+ return arr
+
+ def GetLibraryClassObjs(self):
+ return self.GetFileObj().GetSectionObjectsByName('libraryclasses')
+
+ def Modify(self, modify=True, modifiedObj=None):
+ if modify:
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+ else:
+ if self.GetFileObj().IsModified():
+ return
+
+ self._isModify = modify
+ self.GetParent().Modify(modify, self)
+
+ def GetLibraryClassHeaderPathByName(self, clsname):
+ objs = self.GetLibraryClassObjs()
+ for obj in objs:
+ if obj.GetClassName() == clsname:
+ return obj.GetHeaderFile()
+ return None
+
+class DepexItem(object):
+ def __init__(self, parent, infObj):
+ self._parent = parent
+ self._infObj = infObj
+
+ def GetDepexString(self):
+ return str(self._infObj)
+
+ def GetInfObject(self):
+ return self._infObj
+
+class ModulePcd(object):
+ _type_mapping = {'FeaturePcd': 'PcdsFeatureFlag',
+ 'FixedPcd': 'PcdsFixedAtBuild',
+ 'PatchPcd': 'PcdsPatchableInModule'}
+
+ def __init__(self, parent, name, infObj, pcdItem):
+ assert issubclass(parent.__class__, Module), "Module's PCD's parent must be module!"
+ assert pcdItem is not None, 'Pcd %s does not in some package!' % name
+
+ self._name = name
+ self._parent = parent
+ self._pcdItem = pcdItem
+ self._infObj = infObj
+
+ def GetName(self):
+ return self._name
+
+ def GetParent(self):
+ return self._name
+
+ def GetArch(self):
+ return self._parent.GetArch()
+
+ def Destroy(self):
+ self._pcdItem.DeRef(self._parent)
+ self._infObj = None
+
+ def GetBuildObj(self):
+ platformInfos = self._parent.GetPlatform().GetPcdBuildObjs(self._name, self.GetArch())
+ modulePcdType = self._infObj.GetPcdType()
+
+ # if platform do not gives pcd's value, get default value from package
+ if len(platformInfos) == 0:
+ if modulePcdType.lower() == 'pcd':
+ return self._pcdItem.GetDecObject()
+ else:
+ for obj in self._pcdItem.GetDecObjects():
+ if modulePcdType not in self._type_mapping.keys():
+ ErrorMsg("Invalid PCD type %s" % modulePcdType)
+ return None
+
+ if self._type_mapping[modulePcdType] == obj.GetPcdType():
+ return obj
+ ErrorMsg ('Module PCD type %s does not in valied range [%s] in package!' % \
+ (modulePcdType))
+ else:
+ if modulePcdType.lower() == 'pcd':
+ if len(platformInfos) > 1:
+ WarnMsg("Find more than one value for PCD %s in platform %s" % \
+ (self._name, self._parent.GetPlatform().GetFilename()))
+ return platformInfos[0]
+ else:
+ for obj in platformInfos:
+ if modulePcdType not in self._type_mapping.keys():
+ ErrorMsg("Invalid PCD type %s" % modulePcdType)
+ return None
+
+ if self._type_mapping[modulePcdType] == obj.GetPcdType():
+ return obj
+
+ ErrorMsg('Can not find value for pcd %s in pcd type %s' % \
+ (self._name, modulePcdType))
+ return None
+
+
+class SurfaceItem(object):
+ _objs = {}
+
+ def __new__(cls, *args, **kwargs):
+ """Maintain only a single instance of this object
+ @return: instance of this class
+
+ """
+ name = args[0]
+ parent = args[1]
+ fileObj = args[2]
+ if issubclass(parent.__class__, Package):
+ if name in cls._objs.keys():
+ ErrorMsg("%s item is duplicated defined in packages: %s and %s" %
+ (name, parent.GetFilename(), cls._objs[name].GetParent().GetFilename()))
+ return None
+ obj = object.__new__(cls)
+ cls._objs[name] = obj
+ return obj
+ elif issubclass(parent.__class__, Module):
+ if name not in cls._objs.keys():
+ ErrorMsg("%s item does not defined in any package! It is used by module %s" % \
+ (name, parent.GetFilename()))
+ return None
+ return cls._objs[name]
+
+ return None
+
+
+ def __init__(self, name, parent, fileObj):
+ if issubclass(parent.__class__, Package):
+ self._name = name
+ self._parent = parent
+ self._decObj = [fileObj]
+ self._refMods = {}
+ else:
+ self.RefModule(parent, fileObj)
+
+ @classmethod
+ def GetObjectDict(cls):
+ return cls._objs
+
+ def GetParent(self):
+ return self._parent
+
+ def GetReference(self):
+ return self._refMods
+
+ def RefModule(self, mObj, infObj):
+ if mObj in self._refMods.keys():
+ return
+ self._refMods[mObj] = infObj
+
+ def DeRef(self, mObj):
+ if mObj not in self._refMods.keys():
+ WarnMsg("%s is not referenced by module %s" % (self._name, mObj.GetFilename()))
+ return
+ del self._refMods[mObj]
+
+ def Destroy(self):
+ self._refMods.clear()
+ cls = self.__class__
+ del cls._objs[self._name]
+
+ def GetName(self):
+ return self._name
+
+ def GetDecObject(self):
+ return self._decObj[0]
+
+ def GetDecObjects(self):
+ return self._decObj
+
+class PcdItem(SurfaceItem):
+ def AddDecObj(self, fileObj):
+ for decObj in self._decObj:
+ if decObj.GetFilename() != fileObj.GetFilename():
+ ErrorMsg("Pcd %s defined in more than one packages : %s and %s" % \
+ (self._name, decObj.GetFilename(), fileObj.GetFilename()))
+ return
+ if decObj.GetPcdType() == fileObj.GetPcdType() and \
+ decObj.GetArch().lower() == fileObj.GetArch():
+ ErrorMsg("Pcd %s is duplicated defined in pcd type %s in package %s" % \
+ (self._name, decObj.GetPcdType(), decObj.GetFilename()))
+ return
+ self._decObj.append(fileObj)
+
+ def GetValidPcdType(self):
+ types = []
+ for obj in self._decObj:
+ if obj.GetPcdType() not in types:
+ types += obj.GetPcdType()
+ return types
+
+class GuidItem(SurfaceItem):
+ pass
+
+class PpiItem(SurfaceItem):
+ pass
+
+class ProtocolItem(SurfaceItem):
+ pass