]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/msa2inf/EdkIIWorkspaceGuidsInfo.py
MdeModulePkg: Fix build warning on Xhci driver with XCode 32 tool chain.
[mirror_edk2.git] / BaseTools / Source / Python / msa2inf / EdkIIWorkspaceGuidsInfo.py
1 ## @file
2 # Collects the Guid Information in current workspace.
3 #
4 # Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
9 #
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 #
13
14 ##
15 # Import Modules
16 #
17 import os
18 import fnmatch
19 from Common.EdkIIWorkspace import EdkIIWorkspace
20 from Common.MigrationUtilities import *
21
22 ## A class for EdkII work space to resolve Guids.
23 #
24 # This class inherits from EdkIIWorkspace and collects the Guids information
25 # in current workspace. The Guids information is important to translate the
26 # package Guids and recommended library instances Guids to relative file path
27 # (to workspace directory) in MSA files.
28 #
29 class EdkIIWorkspaceGuidsInfo(EdkIIWorkspace):
30
31 ## The classconstructor.
32 #
33 # The constructor initialize workspace directory. It does not collect
34 # pakage and module Guids info at initialization; instead, it collects them
35 # on the fly.
36 #
37 # @param self The object pointer.
38 #
39 def __init__(self):
40 # Initialize parent class.
41 EdkIIWorkspace.__init__(self)
42 # The internal map from Guid to FilePath.
43 self.__GuidToFilePath = {}
44 # The internal package directory list.
45 self.__PackageDirList = []
46 # The internal flag to indicate whether package Guids info has been
47 # to avoid re-collection collected.
48 self.__PackageGuidInitialized = False
49 # The internal flag to indicate whether module Guids info has been
50 # to avoid re-collection collected.
51 self.__ModuleGuidInitialized = False
52
53 ## Add Guid, Version and FilePath to Guids database.
54 #
55 # Add Guid, Version and FilePath to Guids database. It constructs a map
56 # table from Guid, Version to FilePath internally. If also detects possible
57 # Guid collision. For now, the version information is simply ignored and
58 # Guid value itself acts as master key.
59 #
60 # @param self The object pointer.
61 # @param Guid The Guid Value.
62 # @param Version The version information
63 #
64 # @retval True The Guid value is successfully added to map table.
65 # @retval False The Guid is an empty string or the map table
66 # already contains a same Guid.
67 #
68 def __AddGuidToFilePath(self, Guid, Version, FilePath):
69 if Guid == "":
70 EdkLogger.info("Cannot find Guid in file %s" % FilePath)
71 return False
72 #Add the Guid value to map table to ensure case insensitive comparison.
73 OldFilePath = self.__GuidToFilePath.setdefault(Guid.lower(), FilePath)
74 if OldFilePath == FilePath:
75 EdkLogger.verbose("File %s has new Guid '%s'" % (FilePath, Guid))
76 return True
77 else:
78 EdkLogger.info("File %s has duplicate Guid with & %s" % (FilePath, OldFilePath))
79 return False
80
81
82 ## Gets file information from a module description file.
83 #
84 # Extracts Module Name, File Guid and Version number from INF, MSA and NMSA
85 # file. It supports to exact such information from text based INF file or
86 # XML based (N)MSA file.
87 #
88 # @param self The object pointer.
89 # @param FileName The input module file name.
90 #
91 # @retval True This module file represents a new module discovered
92 # in current workspace.
93 # @retval False This module file is not regarded as a valid module.
94 # The File Guid cannot be extracted or the another
95 # file with the same Guid already exists
96 #
97 def __GetModuleFileInfo(self, FileName):
98 if fnmatch.fnmatch(FileName, "*.inf"):
99 TagTuple = ("BASE_NAME", "FILE_GUID", "VERSION_STRING")
100 (Name, Guid, Version) = GetTextFileInfo(FileName, TagTuple)
101 else :
102 XmlTag1 = "ModuleSurfaceArea/MsaHeader/ModuleName"
103 XmlTag2 = "ModuleSurfaceArea/MsaHeader/GuidValue"
104 XmlTag3 = "ModuleSurfaceArea/MsaHeader/Version"
105 TagTuple = (XmlTag1, XmlTag2, XmlTag3)
106 (Name, Guid, Version) = GetXmlFileInfo(FileName, TagTuple)
107
108 return self.__AddGuidToFilePath(Guid, Version, FileName)
109
110
111 ## Gets file information from a package description file.
112 #
113 # Extracts Package Name, File Guid and Version number from INF, SPD and NSPD
114 # file. It supports to exact such information from text based DEC file or
115 # XML based (N)SPD file. EDK Compatibility Package is hardcoded to be
116 # ignored since no EDKII INF file depends on that package.
117 #
118 # @param self The object pointer.
119 # @param FileName The input package file name.
120 #
121 # @retval True This package file represents a new package
122 # discovered in current workspace.
123 # @retval False This package is not regarded as a valid package.
124 # The File Guid cannot be extracted or the another
125 # file with the same Guid already exists
126 #
127 def __GetPackageFileInfo(self, FileName):
128 if fnmatch.fnmatch(FileName, "*.dec"):
129 TagTuple = ("PACKAGE_NAME", "PACKAGE_GUID", "PACKAGE_VERSION")
130 (Name, Guid, Version) = GetTextFileInfo(FileName, TagTuple)
131 else:
132 XmlTag1 = "PackageSurfaceArea/SpdHeader/PackageName"
133 XmlTag2 = "PackageSurfaceArea/SpdHeader/GuidValue"
134 XmlTag3 = "PackageSurfaceArea/SpdHeader/Version"
135 TagTuple = (XmlTag1, XmlTag2, XmlTag3)
136 (Name, Guid, Version) = GetXmlFileInfo(FileName, TagTuple)
137
138 if Name == "EdkCompatibilityPkg":
139 # Do not scan EDK compatibitilty package to avoid Guid collision
140 # with those in EDK Glue Library.
141 EdkLogger.verbose("Bypass EDK Compatibility Pkg")
142 return False
143
144 return self.__AddGuidToFilePath(Guid, Version, FileName)
145
146 ## Iterate on all package files listed in framework database file.
147 #
148 # Yields all package description files listed in framework database files.
149 # The framework database file describes the packages current workspace
150 # includes.
151 #
152 # @param self The object pointer.
153 #
154 def __FrameworkDatabasePackageFiles(self):
155 XmlFrameworkDb = XmlParseFile(self.WorkspaceFile)
156 XmlTag = "FrameworkDatabase/PackageList/Filename"
157 for PackageFile in XmlElementList(XmlFrameworkDb, XmlTag):
158 yield os.path.join(self.WorkspaceDir, PackageFile)
159
160
161 ## Iterate on all package files in current workspace directory.
162 #
163 # Yields all package description files listed in current workspace
164 # directory. This happens when no framework database file exists.
165 #
166 # @param self The object pointer.
167 #
168 def __TraverseAllPackageFiles(self):
169 for Path, Dirs, Files in os.walk(self.WorkspaceDir):
170 # Ignore svn version control directory.
171 if ".svn" in Dirs:
172 Dirs.remove(".svn")
173 if "Build" in Dirs:
174 Dirs.remove("Build")
175 # Assume priority from high to low: DEC, NSPD, SPD.
176 PackageFiles = fnmatch.filter(Files, "*.dec")
177 if len(PackageFiles) == 0:
178 PackageFiles = fnmatch.filter(Files, "*.nspd")
179 if len(PackageFiles) == 0:
180 PackageFiles = fnmatch.filter(Files, "*.spd")
181
182 for File in PackageFiles:
183 # Assume no more package decription file in sub-directory.
184 del Dirs[:]
185 yield os.path.join(Path, File)
186
187 ## Iterate on all module files in current package directory.
188 #
189 # Yields all module description files listed in current package
190 # directory.
191 #
192 # @param self The object pointer.
193 #
194 def __TraverseAllModuleFiles(self):
195 for PackageDir in self.__PackageDirList:
196 for Path, Dirs, Files in os.walk(PackageDir):
197 # Ignore svn version control directory.
198 if ".svn" in Dirs:
199 Dirs.remove(".svn")
200 # Assume priority from high to low: INF, NMSA, MSA.
201 ModuleFiles = fnmatch.filter(Files, "*.inf")
202 if len(ModuleFiles) == 0:
203 ModuleFiles = fnmatch.filter(Files, "*.nmsa")
204 if len(ModuleFiles) == 0:
205 ModuleFiles = fnmatch.filter(Files, "*.msa")
206
207 for File in ModuleFiles:
208 yield os.path.join(Path, File)
209
210 ## Initialize package Guids info mapping table.
211 #
212 # Collects all package guids map to package decription file path. This
213 # function is invokes on demand to avoid unnecessary directory scan.
214 #
215 # @param self The object pointer.
216 #
217 def __InitializePackageGuidInfo(self):
218 if self.__PackageGuidInitialized:
219 return
220
221 EdkLogger.verbose("Start to collect Package Guids Info.")
222
223 WorkspaceFile = os.path.join("Conf", "FrameworkDatabase.db")
224 self.WorkspaceFile = os.path.join(self.WorkspaceDir, WorkspaceFile)
225
226 # Try to find the frameworkdatabase file to discover package lists
227 if os.path.exists(self.WorkspaceFile):
228 TraversePackage = self.__FrameworkDatabasePackageFiles
229 EdkLogger.verbose("Package list bases on: %s" % self.WorkspaceFile)
230 else:
231 TraversePackage = self.__TraverseAllPackageFiles
232 EdkLogger.verbose("Package list in: %s" % self.WorkspaceDir)
233
234 for FileName in TraversePackage():
235 if self.__GetPackageFileInfo(FileName):
236 PackageDir = os.path.dirname(FileName)
237 EdkLogger.verbose("Find new package directory %s" % PackageDir)
238 self.__PackageDirList.append(PackageDir)
239
240 self.__PackageGuidInitialized = True
241
242 ## Initialize module Guids info mapping table.
243 #
244 # Collects all module guids map to module decription file path. This
245 # function is invokes on demand to avoid unnecessary directory scan.
246 #
247 # @param self The object pointer.
248 #
249 def __InitializeModuleGuidInfo(self):
250 if self.__ModuleGuidInitialized:
251 return
252 EdkLogger.verbose("Start to collect Module Guids Info")
253
254 self.__InitializePackageGuidInfo()
255 for FileName in self.__TraverseAllModuleFiles():
256 if self.__GetModuleFileInfo(FileName):
257 EdkLogger.verbose("Find new module %s" % FileName)
258
259 self.__ModuleGuidInitialized = True
260
261 ## Get Package file path by Package guid and Version.
262 #
263 # Translates the Package Guid and Version to a file path relative
264 # to workspace directory. If no package in current workspace match the
265 # input Guid, an empty file path is returned. For now, the version
266 # value is simply ignored.
267 #
268 # @param self The object pointer.
269 # @param Guid The Package Guid value to look for.
270 # @param Version The Package Version value to look for.
271 #
272 def ResolvePackageFilePath(self, Guid, Version = ""):
273 self.__InitializePackageGuidInfo()
274
275 EdkLogger.verbose("Resolve Package Guid '%s'" % Guid)
276 FileName = self.__GuidToFilePath.get(Guid.lower(), "")
277 if FileName == "":
278 EdkLogger.info("Cannot resolve Package Guid '%s'" % Guid)
279 else:
280 FileName = self.WorkspaceRelativePath(FileName)
281 FileName = os.path.splitext(FileName)[0] + ".dec"
282 FileName = FileName.replace("\\", "/")
283 return FileName
284
285 ## Get Module file path by Package guid and Version.
286 #
287 # Translates the Module Guid and Version to a file path relative
288 # to workspace directory. If no module in current workspace match the
289 # input Guid, an empty file path is returned. For now, the version
290 # value is simply ignored.
291 #
292 # @param self The object pointer.
293 # @param Guid The Module Guid value to look for.
294 # @param Version The Module Version value to look for.
295 #
296 def ResolveModuleFilePath(self, Guid, Version = ""):
297 self.__InitializeModuleGuidInfo()
298
299 EdkLogger.verbose("Resolve Module Guid '%s'" % Guid)
300 FileName = self.__GuidToFilePath.get(Guid.lower(), "")
301 if FileName == "":
302 EdkLogger.info("Cannot resolve Module Guid '%s'" % Guid)
303 else:
304 FileName = self.WorkspaceRelativePath(FileName)
305 FileName = os.path.splitext(FileName)[0] + ".inf"
306 FileName = FileName.replace("\\", "/")
307 return FileName
308
309 # A global class object of EdkIIWorkspaceGuidsInfo for external reference.
310 gEdkIIWorkspaceGuidsInfo = EdkIIWorkspaceGuidsInfo()
311
312 # This acts like the main() function for the script, unless it is 'import'ed
313 # into another script.
314 if __name__ == '__main__':
315 # Test the translation of package Guid.
316 MdePkgGuid = "1E73767F-8F52-4603-AEB4-F29B510B6766"
317 OldMdePkgGuid = "5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"
318 print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(MdePkgGuid)
319 print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(OldMdePkgGuid)
320
321 # Test the translation of module Guid.
322 UefiLibGuid = "3a004ba5-efe0-4a61-9f1a-267a46ae5ba9"
323 UefiDriverModelLibGuid = "52af22ae-9901-4484-8cdc-622dd5838b09"
324 print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(UefiLibGuid)
325 print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(UefiDriverModelLibGuid)