diff options
Diffstat (limited to 'BaseTools/Source/Python/msa2inf/EdkIIWorkspaceGuidsInfo.py')
-rw-r--r-- | BaseTools/Source/Python/msa2inf/EdkIIWorkspaceGuidsInfo.py | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/BaseTools/Source/Python/msa2inf/EdkIIWorkspaceGuidsInfo.py b/BaseTools/Source/Python/msa2inf/EdkIIWorkspaceGuidsInfo.py new file mode 100644 index 0000000000..f1c8d60d75 --- /dev/null +++ b/BaseTools/Source/Python/msa2inf/EdkIIWorkspaceGuidsInfo.py @@ -0,0 +1,325 @@ +## @file
+# Collects the Guid Information in current workspace.
+#
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+##
+# Import Modules
+#
+import os
+import fnmatch
+from Common.EdkIIWorkspace import EdkIIWorkspace
+from Common.MigrationUtilities import *
+
+## A class for EdkII work space to resolve Guids.
+#
+# This class inherits from EdkIIWorkspace and collects the Guids information
+# in current workspace. The Guids information is important to translate the
+# package Guids and recommended library instances Guids to relative file path
+# (to workspace directory) in MSA files.
+#
+class EdkIIWorkspaceGuidsInfo(EdkIIWorkspace):
+
+ ## The classconstructor.
+ #
+ # The constructor initialize workspace directory. It does not collect
+ # pakage and module Guids info at initialization; instead, it collects them
+ # on the fly.
+ #
+ # @param self The object pointer.
+ #
+ def __init__(self):
+ # Initialize parent class.
+ EdkIIWorkspace.__init__(self)
+ # The internal map from Guid to FilePath.
+ self.__GuidToFilePath = {}
+ # The internal package directory list.
+ self.__PackageDirList = []
+ # The internal flag to indicate whether package Guids info has been
+ # to avoid re-collection collected.
+ self.__PackageGuidInitialized = False
+ # The internal flag to indicate whether module Guids info has been
+ # to avoid re-collection collected.
+ self.__ModuleGuidInitialized = False
+
+ ## Add Guid, Version and FilePath to Guids database.
+ #
+ # Add Guid, Version and FilePath to Guids database. It constructs a map
+ # table from Guid, Version to FilePath internally. If also detects possible
+ # Guid collision. For now, the version information is simply ignored and
+ # Guid value itself acts as master key.
+ #
+ # @param self The object pointer.
+ # @param Guid The Guid Value.
+ # @param Version The version information
+ #
+ # @retval True The Guid value is successfully added to map table.
+ # @retval False The Guid is an empty string or the map table
+ # already contains a same Guid.
+ #
+ def __AddGuidToFilePath(self, Guid, Version, FilePath):
+ if Guid == "":
+ EdkLogger.info("Cannot find Guid in file %s" % FilePath)
+ return False
+ #Add the Guid value to map table to ensure case insensitive comparison.
+ OldFilePath = self.__GuidToFilePath.setdefault(Guid.lower(), FilePath)
+ if OldFilePath == FilePath:
+ EdkLogger.verbose("File %s has new Guid '%s'" % (FilePath, Guid))
+ return True
+ else:
+ EdkLogger.info("File %s has duplicate Guid with & %s" % (FilePath, OldFilePath))
+ return False
+
+
+ ## Gets file information from a module description file.
+ #
+ # Extracts Module Name, File Guid and Version number from INF, MSA and NMSA
+ # file. It supports to exact such information from text based INF file or
+ # XML based (N)MSA file.
+ #
+ # @param self The object pointer.
+ # @param FileName The input module file name.
+ #
+ # @retval True This module file represents a new module discovered
+ # in current workspace.
+ # @retval False This module file is not regarded as a valid module.
+ # The File Guid cannot be extracted or the another
+ # file with the same Guid already exists
+ #
+ def __GetModuleFileInfo(self, FileName):
+ if fnmatch.fnmatch(FileName, "*.inf"):
+ TagTuple = ("BASE_NAME", "FILE_GUID", "VERSION_STRING")
+ (Name, Guid, Version) = GetTextFileInfo(FileName, TagTuple)
+ else :
+ XmlTag1 = "ModuleSurfaceArea/MsaHeader/ModuleName"
+ XmlTag2 = "ModuleSurfaceArea/MsaHeader/GuidValue"
+ XmlTag3 = "ModuleSurfaceArea/MsaHeader/Version"
+ TagTuple = (XmlTag1, XmlTag2, XmlTag3)
+ (Name, Guid, Version) = GetXmlFileInfo(FileName, TagTuple)
+
+ return self.__AddGuidToFilePath(Guid, Version, FileName)
+
+
+ ## Gets file information from a package description file.
+ #
+ # Extracts Package Name, File Guid and Version number from INF, SPD and NSPD
+ # file. It supports to exact such information from text based DEC file or
+ # XML based (N)SPD file. EDK Compatibility Package is hardcoded to be
+ # ignored since no EDKII INF file depends on that package.
+ #
+ # @param self The object pointer.
+ # @param FileName The input package file name.
+ #
+ # @retval True This package file represents a new package
+ # discovered in current workspace.
+ # @retval False This package is not regarded as a valid package.
+ # The File Guid cannot be extracted or the another
+ # file with the same Guid already exists
+ #
+ def __GetPackageFileInfo(self, FileName):
+ if fnmatch.fnmatch(FileName, "*.dec"):
+ TagTuple = ("PACKAGE_NAME", "PACKAGE_GUID", "PACKAGE_VERSION")
+ (Name, Guid, Version) = GetTextFileInfo(FileName, TagTuple)
+ else:
+ XmlTag1 = "PackageSurfaceArea/SpdHeader/PackageName"
+ XmlTag2 = "PackageSurfaceArea/SpdHeader/GuidValue"
+ XmlTag3 = "PackageSurfaceArea/SpdHeader/Version"
+ TagTuple = (XmlTag1, XmlTag2, XmlTag3)
+ (Name, Guid, Version) = GetXmlFileInfo(FileName, TagTuple)
+
+ if Name == "EdkCompatibilityPkg":
+ # Do not scan EDK compatibitilty package to avoid Guid collision
+ # with those in EDK Glue Library.
+ EdkLogger.verbose("Bypass EDK Compatibility Pkg")
+ return False
+
+ return self.__AddGuidToFilePath(Guid, Version, FileName)
+
+ ## Iterate on all package files listed in framework database file.
+ #
+ # Yields all package description files listed in framework database files.
+ # The framework database file describes the packages current workspace
+ # includes.
+ #
+ # @param self The object pointer.
+ #
+ def __FrameworkDatabasePackageFiles(self):
+ XmlFrameworkDb = XmlParseFile(self.WorkspaceFile)
+ XmlTag = "FrameworkDatabase/PackageList/Filename"
+ for PackageFile in XmlElementList(XmlFrameworkDb, XmlTag):
+ yield os.path.join(self.WorkspaceDir, PackageFile)
+
+
+ ## Iterate on all package files in current workspace directory.
+ #
+ # Yields all package description files listed in current workspace
+ # directory. This happens when no framework database file exists.
+ #
+ # @param self The object pointer.
+ #
+ def __TraverseAllPackageFiles(self):
+ for Path, Dirs, Files in os.walk(self.WorkspaceDir):
+ # Ignore svn version control directory.
+ if ".svn" in Dirs:
+ Dirs.remove(".svn")
+ if "Build" in Dirs:
+ Dirs.remove("Build")
+ # Assume priority from high to low: DEC, NSPD, SPD.
+ PackageFiles = fnmatch.filter(Files, "*.dec")
+ if len(PackageFiles) == 0:
+ PackageFiles = fnmatch.filter(Files, "*.nspd")
+ if len(PackageFiles) == 0:
+ PackageFiles = fnmatch.filter(Files, "*.spd")
+
+ for File in PackageFiles:
+ # Assume no more package decription file in sub-directory.
+ del Dirs[:]
+ yield os.path.join(Path, File)
+
+ ## Iterate on all module files in current package directory.
+ #
+ # Yields all module description files listed in current package
+ # directory.
+ #
+ # @param self The object pointer.
+ #
+ def __TraverseAllModuleFiles(self):
+ for PackageDir in self.__PackageDirList:
+ for Path, Dirs, Files in os.walk(PackageDir):
+ # Ignore svn version control directory.
+ if ".svn" in Dirs:
+ Dirs.remove(".svn")
+ # Assume priority from high to low: INF, NMSA, MSA.
+ ModuleFiles = fnmatch.filter(Files, "*.inf")
+ if len(ModuleFiles) == 0:
+ ModuleFiles = fnmatch.filter(Files, "*.nmsa")
+ if len(ModuleFiles) == 0:
+ ModuleFiles = fnmatch.filter(Files, "*.msa")
+
+ for File in ModuleFiles:
+ yield os.path.join(Path, File)
+
+ ## Initialize package Guids info mapping table.
+ #
+ # Collects all package guids map to package decription file path. This
+ # function is invokes on demand to avoid unnecessary directory scan.
+ #
+ # @param self The object pointer.
+ #
+ def __InitializePackageGuidInfo(self):
+ if self.__PackageGuidInitialized:
+ return
+
+ EdkLogger.verbose("Start to collect Package Guids Info.")
+
+ WorkspaceFile = os.path.join("Conf", "FrameworkDatabase.db")
+ self.WorkspaceFile = os.path.join(self.WorkspaceDir, WorkspaceFile)
+
+ # Try to find the frameworkdatabase file to discover package lists
+ if os.path.exists(self.WorkspaceFile):
+ TraversePackage = self.__FrameworkDatabasePackageFiles
+ EdkLogger.verbose("Package list bases on: %s" % self.WorkspaceFile)
+ else:
+ TraversePackage = self.__TraverseAllPackageFiles
+ EdkLogger.verbose("Package list in: %s" % self.WorkspaceDir)
+
+ for FileName in TraversePackage():
+ if self.__GetPackageFileInfo(FileName):
+ PackageDir = os.path.dirname(FileName)
+ EdkLogger.verbose("Find new package directory %s" % PackageDir)
+ self.__PackageDirList.append(PackageDir)
+
+ self.__PackageGuidInitialized = True
+
+ ## Initialize module Guids info mapping table.
+ #
+ # Collects all module guids map to module decription file path. This
+ # function is invokes on demand to avoid unnecessary directory scan.
+ #
+ # @param self The object pointer.
+ #
+ def __InitializeModuleGuidInfo(self):
+ if self.__ModuleGuidInitialized:
+ return
+ EdkLogger.verbose("Start to collect Module Guids Info")
+
+ self.__InitializePackageGuidInfo()
+ for FileName in self.__TraverseAllModuleFiles():
+ if self.__GetModuleFileInfo(FileName):
+ EdkLogger.verbose("Find new module %s" % FileName)
+
+ self.__ModuleGuidInitialized = True
+
+ ## Get Package file path by Package guid and Version.
+ #
+ # Translates the Package Guid and Version to a file path relative
+ # to workspace directory. If no package in current workspace match the
+ # input Guid, an empty file path is returned. For now, the version
+ # value is simply ignored.
+ #
+ # @param self The object pointer.
+ # @param Guid The Package Guid value to look for.
+ # @param Version The Package Version value to look for.
+ #
+ def ResolvePackageFilePath(self, Guid, Version = ""):
+ self.__InitializePackageGuidInfo()
+
+ EdkLogger.verbose("Resolve Package Guid '%s'" % Guid)
+ FileName = self.__GuidToFilePath.get(Guid.lower(), "")
+ if FileName == "":
+ EdkLogger.info("Cannot resolve Package Guid '%s'" % Guid)
+ else:
+ FileName = self.WorkspaceRelativePath(FileName)
+ FileName = os.path.splitext(FileName)[0] + ".dec"
+ FileName = FileName.replace("\\", "/")
+ return FileName
+
+ ## Get Module file path by Package guid and Version.
+ #
+ # Translates the Module Guid and Version to a file path relative
+ # to workspace directory. If no module in current workspace match the
+ # input Guid, an empty file path is returned. For now, the version
+ # value is simply ignored.
+ #
+ # @param self The object pointer.
+ # @param Guid The Module Guid value to look for.
+ # @param Version The Module Version value to look for.
+ #
+ def ResolveModuleFilePath(self, Guid, Version = ""):
+ self.__InitializeModuleGuidInfo()
+
+ EdkLogger.verbose("Resolve Module Guid '%s'" % Guid)
+ FileName = self.__GuidToFilePath.get(Guid.lower(), "")
+ if FileName == "":
+ EdkLogger.info("Cannot resolve Module Guid '%s'" % Guid)
+ else:
+ FileName = self.WorkspaceRelativePath(FileName)
+ FileName = os.path.splitext(FileName)[0] + ".inf"
+ FileName = FileName.replace("\\", "/")
+ return FileName
+
+# A global class object of EdkIIWorkspaceGuidsInfo for external reference.
+gEdkIIWorkspaceGuidsInfo = EdkIIWorkspaceGuidsInfo()
+
+# This acts like the main() function for the script, unless it is 'import'ed
+# into another script.
+if __name__ == '__main__':
+ # Test the translation of package Guid.
+ MdePkgGuid = "1E73767F-8F52-4603-AEB4-F29B510B6766"
+ OldMdePkgGuid = "5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"
+ print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(MdePkgGuid)
+ print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(OldMdePkgGuid)
+
+ # Test the translation of module Guid.
+ UefiLibGuid = "3a004ba5-efe0-4a61-9f1a-267a46ae5ba9"
+ UefiDriverModelLibGuid = "52af22ae-9901-4484-8cdc-622dd5838b09"
+ print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(UefiLibGuid)
+ print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(UefiDriverModelLibGuid)
|