This tool is used to generate the document for edk2 packages. The
generated document will be in UDK release. For example, UDK2017
document can be found in:
https://github.com/tianocore/tianocore.github.io/wiki/UDK2017#documentation
Cc: Star Zeng <star.zeng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
(cherry picked from commit 7ccc9c954c)
		
	
		
			
				
	
	
		
			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 not cls._objs.has_key("None"):
 | |
|             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 self._objs.has_key(key), "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 != 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 not cls._objs.has_key(relativePath):
 | |
|             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() == 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 != 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 != 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 != 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 == 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] != 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 != 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 != None:
 | |
|                 protocol.DeRef(self)
 | |
|         del self._protocols[:]
 | |
| 
 | |
|         for guid in self._guids:
 | |
|             if guid != 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 != None:
 | |
|             self._overideLibs = overideLibs
 | |
|         if overideLibs != 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 == 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 == None: continue
 | |
|             ppis += lib._ppis
 | |
|         return ppis
 | |
| 
 | |
|     def GetProtocols(self):
 | |
|         pros = []
 | |
|         pros = self._protocols
 | |
|         for lib in self._libs.values():
 | |
|             if lib == None: continue
 | |
|             pros += lib._protocols
 | |
|         return pros
 | |
| 
 | |
|     def GetGuids(self):
 | |
|         guids = []
 | |
|         guids += self._guids
 | |
|         for lib in self._libs.values():
 | |
|             if lib == None: continue
 | |
|             guids += lib._guids
 | |
|         return guids
 | |
| 
 | |
|     def GetDepexs(self):
 | |
|         deps = []
 | |
|         deps += self._depexs
 | |
|         for lib in self._libs.values():
 | |
|             if lib == None: continue
 | |
|             deps += lib._depexs
 | |
|         return deps
 | |
| 
 | |
|     def IsLibrary(self):
 | |
|         return self.GetFileObj().GetDefine("LIBRARY_CLASS") != 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 == 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 != 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() != 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 != None:
 | |
|                 self._packages.append(package)
 | |
| 
 | |
|     def GetPackages(self):
 | |
|         return self._packages
 | |
| 
 | |
|     def GetPcdObjects(self):
 | |
|         if self.GetFileObj() == None:
 | |
|             return []
 | |
| 
 | |
|         return self.GetFileObj().GetSectionObjectsByName('pcd')
 | |
| 
 | |
|     def GetLibraryClassHeaderFilePath(self):
 | |
|         lcname = self.GetFileObj().GetProduceLibraryClass()
 | |
|         if lcname == None: return None
 | |
| 
 | |
|         pkgs = self.GetPackages()
 | |
|         for package in pkgs:
 | |
|             path = package.GetLibraryClassHeaderPathByName(lcname)
 | |
|             if path != None:
 | |
|                 return os.path.realpath(os.path.join(package.GetFileObj().GetPackageRootPath(), path))
 | |
|         return None
 | |
| 
 | |
|     def Reload(self, force=False, callback=None):
 | |
|         if callback != 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 != 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 != None:
 | |
|             callback(self, "Searching libraries...")
 | |
|         self._SearchLibraries()
 | |
|         if callback != None:
 | |
|             callback(self, "Searching packages...")
 | |
|         self._SearchPackage()
 | |
|         if callback != 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 != None:
 | |
|                 pcd.Destroy()
 | |
|         for guid in self._guids.values():
 | |
|             if guid != None:
 | |
|                 guid.Destroy()
 | |
|         for protocol in self._protocols.values():
 | |
|             if protocol != None:
 | |
|                 protocol.Destroy()
 | |
|         for ppi in self._ppis.values():
 | |
|             if ppi != 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()] != 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 == 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 != 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
 |