Replace "has_key()" with "in" to be compatible with python3. Based on "futurize -f lib2to3.fixes.fix_has_key" Contributed-under: TianoCore Contribution Agreement 1.1 Cc: Yonghong Zhu <yonghong.zhu@intel.com> Cc: Liming Gao <liming.gao@intel.com> Signed-off-by: Gary Lin <glin@suse.com> Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
		
			
				
	
	
		
			935 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			935 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
## @file
 | 
						|
#
 | 
						|
# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
#
 | 
						|
# This program and the accompanying materials are licensed and made available
 | 
						|
# under the terms and conditions of the BSD License which accompanies this
 | 
						|
# distribution. The full text of the license may be found at
 | 
						|
# http://opensource.org/licenses/bsd-license.php
 | 
						|
#
 | 
						|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
import plugins.EdkPlugins.basemodel.ini as ini
 | 
						|
import plugins.EdkPlugins.edk2.model.dsc as dsc
 | 
						|
import plugins.EdkPlugins.edk2.model.inf as inf
 | 
						|
import plugins.EdkPlugins.edk2.model.dec as 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, *args, **kwargs)
 | 
						|
        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 self._ppis.values()
 | 
						|
 | 
						|
    def GetProtocols(self):
 | 
						|
        return self._protocols.values()
 | 
						|
 | 
						|
    def GetGuids(self):
 | 
						|
        return 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, *args, **kwargs)
 | 
						|
            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
 |