Add a new feature to UPT to support installing
multiple DIST packages in one time.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: hesschen <hesheng.c...@intel.com>
---
 .../Source/Python/UPT/Core/DependencyRules.py      | 18 ++++-
 .../Python/UPT/GenMetaFile/GenMetaFileMisc.py      | 90 +++++++++++++--------
 BaseTools/Source/Python/UPT/InstallPkg.py          | 94 +++++++++++-----------
 BaseTools/Source/Python/UPT/Library/GlobalData.py  |  9 ++-
 BaseTools/Source/Python/UPT/Logger/StringTable.py  |  4 +-
 BaseTools/Source/Python/UPT/ReplacePkg.py          |  8 +-
 BaseTools/Source/Python/UPT/TestInstall.py         |  8 +-
 BaseTools/Source/Python/UPT/UPT.py                 | 16 ++--
 8 files changed, 145 insertions(+), 102 deletions(-)

diff --git a/BaseTools/Source/Python/UPT/Core/DependencyRules.py 
b/BaseTools/Source/Python/UPT/Core/DependencyRules.py
index 57f7b40..909c584 100644
--- a/BaseTools/Source/Python/UPT/Core/DependencyRules.py
+++ b/BaseTools/Source/Python/UPT/Core/DependencyRules.py
@@ -44,12 +44,24 @@ DEPEX_CHECK_PACKAGE_NOT_FOUND, DEPEX_CHECK_DP_NOT_FOUND) = 
(0, 1, 2, 3)
 # @param object:      Inherited from object class
 #
 class DependencyRules(object):
-    def __init__(self, Datab):
+    def __init__(self, Datab, ToBeInstalledPkgList=None):
         self.IpiDb = Datab
         self.WsPkgList = GetWorkspacePackage()
         self.WsModuleList = GetWorkspaceModule()
-        self.PkgsToBeDepend = []
+
+        self.PkgsToBeDepend = [(PkgInfo[1], PkgInfo[2]) for PkgInfo in 
self.WsPkgList]
+
+        # Add package info from the DIST to be installed.
+        
self.PkgsToBeDepend.extend(self.GenToBeInstalledPkgList(ToBeInstalledPkgList))
         
+    def GenToBeInstalledPkgList(self, ToBeInstalledPkgList):
+        RtnList = []
+        for Dist in ToBeInstalledPkgList:
+            for Package in Dist.PackageSurfaceArea:
+                RtnList.append((Package[0], Package[1]))
+
+        return RtnList
+
     ## Check whether a module exists by checking the Guid+Version+Name+Path 
combination
     #
     # @param Guid:  Guid of a module
@@ -182,7 +194,6 @@ class DependencyRules(object):
     #          False else
     #
     def CheckInstallDpDepexSatisfied(self, DpObj):
-        self.PkgsToBeDepend = [(PkgInfo[1], PkgInfo[2]) for PkgInfo in 
self.WsPkgList]
         return self.CheckDpDepexSatisfied(DpObj)
 
     # # Check whether multiple DP depex satisfied by current workspace for 
Install
@@ -192,7 +203,6 @@ class DependencyRules(object):
     #          False else
     #
     def CheckTestInstallPdDepexSatisfied(self, DpObjList):
-        self.PkgsToBeDepend = [(PkgInfo[1], PkgInfo[2]) for PkgInfo in 
self.WsPkgList]
         for DpObj in DpObjList:
             if self.CheckDpDepexSatisfied(DpObj):
                 for PkgKey in DpObj.PackageSurfaceArea.keys():
diff --git a/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py 
b/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py
index 3c6c9ee..ae8dc85 100644
--- a/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py
+++ b/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py
@@ -79,6 +79,10 @@ def AddExternToDefineSec(SectionDict, Arch, ExternList):
 # Using TokenSpaceGuidValue and Token to obtain PcdName from DEC file
 #
 def ObtainPcdName(Packages, TokenSpaceGuidValue, Token):
+    TokenSpaceGuidName = ''
+    PcdCName = ''
+    TokenSpaceGuidNameFound = False
+
     for PackageDependency in Packages:
         #
         # Generate generic comment
@@ -86,6 +90,7 @@ def ObtainPcdName(Packages, TokenSpaceGuidValue, Token):
         Guid = PackageDependency.GetGuid()
         Version = PackageDependency.GetVersion()
 
+        Path = None
         #
         # find package path/name
         # 
@@ -95,41 +100,58 @@ def ObtainPcdName(Packages, TokenSpaceGuidValue, Token):
                     Path = PkgInfo[3]
                     break
 
-        DecFile = None
-        if Path not in GlobalData.gPackageDict:
-            DecFile = Dec(Path)
-            GlobalData.gPackageDict[Path] = DecFile
-        else:
-            DecFile = GlobalData.gPackageDict[Path]
-
-        DecGuidsDict = DecFile.GetGuidSectionObject().ValueDict
-        DecPcdsDict = DecFile.GetPcdSectionObject().ValueDict
-
-        TokenSpaceGuidName = ''
-        PcdCName = ''
-        TokenSpaceGuidNameFound = False
-
-        #
-        # Get TokenSpaceGuidCName from Guids section 
-        #
-        for GuidKey in DecGuidsDict:
-            GuidList = DecGuidsDict[GuidKey]
-            for GuidItem in GuidList:
-                if TokenSpaceGuidValue.upper() == GuidItem.GuidString.upper():
-                    TokenSpaceGuidName = GuidItem.GuidCName
-                    TokenSpaceGuidNameFound = True
+        # The dependency package in workspace
+        if Path:
+            DecFile = None
+            if Path not in GlobalData.gPackageDict:
+                DecFile = Dec(Path)
+                GlobalData.gPackageDict[Path] = DecFile
+            else:
+                DecFile = GlobalData.gPackageDict[Path]
+
+            DecGuidsDict = DecFile.GetGuidSectionObject().ValueDict
+            DecPcdsDict = DecFile.GetPcdSectionObject().ValueDict
+
+            TokenSpaceGuidName = ''
+            PcdCName = ''
+            TokenSpaceGuidNameFound = False
+
+            #
+            # Get TokenSpaceGuidCName from Guids section
+            #
+            for GuidKey in DecGuidsDict:
+                GuidList = DecGuidsDict[GuidKey]
+                for GuidItem in GuidList:
+                    if TokenSpaceGuidValue.upper() == 
GuidItem.GuidString.upper():
+                        TokenSpaceGuidName = GuidItem.GuidCName
+                        TokenSpaceGuidNameFound = True
+                        break
+                if TokenSpaceGuidNameFound:
                     break
-            if TokenSpaceGuidNameFound:
-                break
-        #
-        # Retrieve PcdCName from Pcds Section
-        #
-        for PcdKey in DecPcdsDict:
-            PcdList = DecPcdsDict[PcdKey]
-            for PcdItem in PcdList:
-                if TokenSpaceGuidName == PcdItem.TokenSpaceGuidCName and Token 
== PcdItem.TokenValue:
-                    PcdCName = PcdItem.TokenCName
-                    return TokenSpaceGuidName, PcdCName
+            #
+            # Retrieve PcdCName from Pcds Section
+            #
+            for PcdKey in DecPcdsDict:
+                PcdList = DecPcdsDict[PcdKey]
+                for PcdItem in PcdList:
+                    if TokenSpaceGuidName == PcdItem.TokenSpaceGuidCName and 
Token == PcdItem.TokenValue:
+                        PcdCName = PcdItem.TokenCName
+                        return TokenSpaceGuidName, PcdCName
+
+        # The dependency package in ToBeInstalledDist
+        else:
+            for Dist in GlobalData.gTO_BE_INSTALLED_DIST_LIST:
+                for Package in Dist.PackageSurfaceArea.values():
+                    if Guid == Package.Guid:
+                        for GuidItem in Package.GuidList:
+                            if TokenSpaceGuidValue.upper() == 
GuidItem.Guid.upper():
+                                TokenSpaceGuidName = GuidItem.CName
+                                TokenSpaceGuidNameFound = True
+                                break
+                        for PcdItem in Package.PcdList:
+                            if TokenSpaceGuidName == 
PcdItem.TokenSpaceGuidCName and Token == PcdItem.Token:
+                                PcdCName = PcdItem.CName
+                                return TokenSpaceGuidName, PcdCName
 
     return TokenSpaceGuidName, PcdCName
 
diff --git a/BaseTools/Source/Python/UPT/InstallPkg.py 
b/BaseTools/Source/Python/UPT/InstallPkg.py
index 0e99d2f..a8d0e1e 100644
--- a/BaseTools/Source/Python/UPT/InstallPkg.py
+++ b/BaseTools/Source/Python/UPT/InstallPkg.py
@@ -1,7 +1,7 @@
 ## @file
 # Install distribution package.
 #
-# Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2011 - 2017, 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 
@@ -133,16 +133,16 @@ def InstallNewFile(WorkspaceDir, File):
 #
 # UnZipDp
 #
-def UnZipDp(WorkspaceDir, DpPkgFileName):
+def UnZipDp(WorkspaceDir, DpPkgFileName, Index=1):
     ContentZipFile = None
     Logger.Quiet(ST.MSG_UZIP_PARSE_XML)
     DistFile = PackageFile(DpPkgFileName)
     
     DpDescFileName, ContentFileName = GetDPFile(DistFile.GetZipFile())
     
-    GlobalData.gUNPACK_DIR = os.path.normpath(os.path.join(WorkspaceDir, 
".tmp"))
-    DistPkgFile = DistFile.UnpackFile(DpDescFileName,
-        os.path.normpath(os.path.join(GlobalData.gUNPACK_DIR, DpDescFileName)))
+    TempDir = os.path.normpath(os.path.join(WorkspaceDir, "Conf/.tmp%s" % 
str(Index)))
+    GlobalData.gUNPACK_DIR.append(TempDir)
+    DistPkgFile = DistFile.UnpackFile(DpDescFileName, 
os.path.normpath(os.path.join(TempDir, DpDescFileName)))
     if not DistPkgFile:
         Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_FILE_BROKEN 
%DpDescFileName)
     
@@ -159,23 +159,15 @@ def UnZipDp(WorkspaceDir, DpPkgFileName):
     #
     # unzip contents.zip file
     #
-    ContentFile = DistFile.UnpackFile(ContentFileName,
-        os.path.normpath(os.path.join(GlobalData.gUNPACK_DIR, 
ContentFileName)))
+    ContentFile = DistFile.UnpackFile(ContentFileName, 
os.path.normpath(os.path.join(TempDir, ContentFileName)))
     if not ContentFile:
         Logger.Error("InstallPkg", FILE_NOT_FOUND,
             ST.ERR_FILE_BROKEN % ContentFileName)
 
-    FilePointer = __FileHookOpen__(ContentFile, "rb")
-    #
-    # Assume no archive comment.
-    #
-    FilePointer.seek(0, SEEK_SET)
-    FilePointer.seek(0, SEEK_END)
     #
     # Get file size
     #                
-    FileSize = FilePointer.tell()
-    FilePointer.close()
+    FileSize = os.path.getsize(ContentFile)
                
     if FileSize != 0:        
         ContentZipFile = PackageFile(ContentFile)
@@ -202,8 +194,8 @@ def GetPackageList(DistPkg, Dep, WorkspaceDir, Options, 
ContentZipFile, ModuleLi
         PackagePath = Path
         Package = DistPkg.PackageSurfaceArea[Guid, Version, Path]
         Logger.Info(ST.MSG_INSTALL_PACKAGE % Package.GetName())
-        if Dep.CheckPackageExists(Guid, Version):
-            Logger.Info(ST.WRN_PACKAGE_EXISTED %(Guid, Version))
+#         if Dep.CheckPackageExists(Guid, Version):
+#             Logger.Info(ST.WRN_PACKAGE_EXISTED %(Guid, Version))
         if Options.UseGuidedPkgPath:
             GuidedPkgPath = "%s_%s_%s" % (Package.GetName(), Guid, Version)
             NewPackagePath = InstallNewPackage(WorkspaceDir, GuidedPkgPath, 
Options.CustomPath)
@@ -509,29 +501,40 @@ def GenToolMisc(DistPkg, WorkspaceDir, ContentZipFile):
 # @param  Options: command Options
 #
 def Main(Options = None):
-    ContentZipFile, DistFile = None, None
-
     try:
         DataBase = GlobalData.gDB
         WorkspaceDir = GlobalData.gWORKSPACE
         if not Options.PackageFile:
             Logger.Error("InstallPkg", OPTION_MISSING, 
ExtraData=ST.ERR_SPECIFY_PACKAGE)
         
-        #
-        # unzip dist.pkg file
-        #
-        DistPkg, ContentZipFile, DpPkgFileName, DistFile = 
UnZipDp(WorkspaceDir, Options.PackageFile)
+        # Get all Dist Info
+        DistInfoList = []
+        DistPkgList = []
+        Index = 1
+        for ToBeInstalledDist in Options.PackageFile:
+            #
+            # unzip dist.pkg file
+            #
+            DistInfoList.append(UnZipDp(WorkspaceDir, ToBeInstalledDist, 
Index))
+            DistPkgList.append(DistInfoList[-1][0])
+            Index += 1
 
-        #
-        # check dependency
-        #
-        Dep = DependencyRules(DataBase)
-        CheckInstallDpx(Dep, DistPkg)
+            #
+            # Add dist
+            #
+            GlobalData.gTO_BE_INSTALLED_DIST_LIST.append(DistInfoList[-1][0])
 
-        #
-        # Install distribution
-        #
-        InstallDp(DistPkg, DpPkgFileName, ContentZipFile, Options, Dep, 
WorkspaceDir, DataBase)
+        # Check for dependency
+        Dep = DependencyRules(DataBase, DistPkgList)
+
+        for ToBeInstalledDist in DistInfoList:
+            CheckInstallDpx(Dep, ToBeInstalledDist[0], ToBeInstalledDist[2])
+
+            #
+            # Install distribution
+            #
+            InstallDp(ToBeInstalledDist[0], ToBeInstalledDist[2], 
ToBeInstalledDist[1],
+                      Options, Dep, WorkspaceDir, DataBase)
         ReturnCode = 0
         
     except FatalError, XExcept:
@@ -556,16 +559,16 @@ def Main(Options = None):
         Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(),
             platform) + format_exc())
     finally:
-        if ReturnCode != UPT_ALREADY_INSTALLED_ERROR:
-            Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_STARTED)
-            if DistFile:
-                DistFile.Close()
-            if ContentZipFile:
-                ContentZipFile.Close()
-            if GlobalData.gUNPACK_DIR:
-                rmtree(GlobalData.gUNPACK_DIR)
-                GlobalData.gUNPACK_DIR = None
-            Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_DONE)
+        Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_STARTED)
+        for ToBeInstalledDist in DistInfoList:
+            if ToBeInstalledDist[3]:
+                ToBeInstalledDist[3].Close()
+            if ToBeInstalledDist[1]:
+                ToBeInstalledDist[1].Close()
+        for TempDir in GlobalData.gUNPACK_DIR:
+            rmtree(TempDir)
+        GlobalData.gUNPACK_DIR = []
+        Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_DONE)
     if ReturnCode == 0:
         Logger.Quiet(ST.MSG_FINISH)
     return ReturnCode
@@ -609,14 +612,15 @@ def BackupDist(DpPkgFileName, Guid, Version, 
WorkspaceDir):
 #   @param  Dep: the DependencyRules instance that used to check dependency
 #   @param  DistPkg: the distribution object
 #
-def CheckInstallDpx(Dep, DistPkg):
+def CheckInstallDpx(Dep, DistPkg, DistPkgFileName):
     #
     # Check distribution package installed or not
     #
     if Dep.CheckDpExists(DistPkg.Header.GetGuid(),
         DistPkg.Header.GetVersion()):
-        Logger.Error("InstallPkg", UPT_ALREADY_INSTALLED_ERROR,
-            ST.WRN_DIST_PKG_INSTALLED)
+        Logger.Error("InstallPkg",
+                     UPT_ALREADY_INSTALLED_ERROR,
+                     ST.WRN_DIST_PKG_INSTALLED % 
os.path.basename(DistPkgFileName))
     #
     # Check distribution dependency (all module dependency should be
     # satisfied)
diff --git a/BaseTools/Source/Python/UPT/Library/GlobalData.py 
b/BaseTools/Source/Python/UPT/Library/GlobalData.py
index 8f446d4..1ae2417 100644
--- a/BaseTools/Source/Python/UPT/Library/GlobalData.py
+++ b/BaseTools/Source/Python/UPT/Library/GlobalData.py
@@ -1,7 +1,7 @@
 ## @file
 # This file is used to define common static strings and global data used by UPT
 #
-# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2011 - 2017, 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 
@@ -87,7 +87,7 @@ gWARNING_AS_ERROR = False
 #
 # Used to specify the temp directory to hold the unpacked distribution files
 #
-gUNPACK_DIR = None
+gUNPACK_DIR = []
 
 #
 # Flag used to mark whether the INF file is Binary INF or not.
@@ -109,3 +109,8 @@ gPackageDict = {}
 # {FilePath: FileObj}
 #
 gLIBINSTANCEDICT = {}
+
+#
+# Store the list of DIST
+#
+gTO_BE_INSTALLED_DIST_LIST = []
diff --git a/BaseTools/Source/Python/UPT/Logger/StringTable.py 
b/BaseTools/Source/Python/UPT/Logger/StringTable.py
index 4c42661..83ae0ae 100644
--- a/BaseTools/Source/Python/UPT/Logger/StringTable.py
+++ b/BaseTools/Source/Python/UPT/Logger/StringTable.py
@@ -1,7 +1,7 @@
 ## @file
 # This file is used to define strings used in the UPT tool
 #
-# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2011 - 2017, 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 
@@ -785,7 +785,7 @@ WRN_MODULE_EXISTED        = _("This module already exists: 
%s")
 WRN_FILE_EXISTED          = _("This file already exists: %s")
 WRN_FILE_NOT_OVERWRITTEN  = \
 _("This file already exist and cannot be overwritten: %s")
-WRN_DIST_PKG_INSTALLED = _("This distribution package has previously been 
installed.")
+WRN_DIST_PKG_INSTALLED = _("This distribution package %s has previously been 
installed.")
 WRN_DIST_NOT_FOUND         = _(
     "Distribution is not found at location %s")
 WRN_MULTI_PCD_RANGES      = _(
diff --git a/BaseTools/Source/Python/UPT/ReplacePkg.py 
b/BaseTools/Source/Python/UPT/ReplacePkg.py
index 9f231f9..efbf68a 100644
--- a/BaseTools/Source/Python/UPT/ReplacePkg.py
+++ b/BaseTools/Source/Python/UPT/ReplacePkg.py
@@ -1,7 +1,7 @@
 ## @file
 # Replace distribution package.
 #
-# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2014 - 2017, 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 
@@ -99,9 +99,9 @@ def Main(Options = None):
             DistFile.Close()
         if ContentZipFile:
             ContentZipFile.Close()
-        if GlobalData.gUNPACK_DIR:
-            rmtree(GlobalData.gUNPACK_DIR)
-            GlobalData.gUNPACK_DIR = None
+        for TempDir in GlobalData.gUNPACK_DIR:
+            rmtree(TempDir)
+        GlobalData.gUNPACK_DIR = []
         Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_DONE)        
 
     if ReturnCode == 0:
diff --git a/BaseTools/Source/Python/UPT/TestInstall.py 
b/BaseTools/Source/Python/UPT/TestInstall.py
index dae4415..899cae5 100644
--- a/BaseTools/Source/Python/UPT/TestInstall.py
+++ b/BaseTools/Source/Python/UPT/TestInstall.py
@@ -1,7 +1,7 @@
 # # @file
 # Test Install distribution package
 #
-# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2017, 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
@@ -90,9 +90,9 @@ def Main(Options=None):
             DistFile.Close()
         if ContentZipFile:
             ContentZipFile.Close()
-        if GlobalData.gUNPACK_DIR:
-            shutil.rmtree(GlobalData.gUNPACK_DIR)
-            GlobalData.gUNPACK_DIR = None
+        for TempDir in GlobalData.gUNPACK_DIR:
+            shutil.rmtree(TempDir)
+        GlobalData.gUNPACK_DIR = []
         Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_DONE)
     if ReturnCode == 0:
         Logger.Quiet(ST.MSG_FINISH)
diff --git a/BaseTools/Source/Python/UPT/UPT.py 
b/BaseTools/Source/Python/UPT/UPT.py
index d98b469..325b96b 100644
--- a/BaseTools/Source/Python/UPT/UPT.py
+++ b/BaseTools/Source/Python/UPT/UPT.py
@@ -120,7 +120,7 @@ def Main():
 
     Parser.add_option("-q", "--quiet", action="store_true", dest="opt_quiet", 
help=ST.HLP_RETURN_AND_DISPLAY)
 
-    Parser.add_option("-i", "--install", action="store", type="string", 
dest="Install_Distribution_Package_File",
+    Parser.add_option("-i", "--install", action="append", type="string", 
dest="Install_Distribution_Package_File",
                       help=ST.HLP_SPECIFY_PACKAGE_NAME_INSTALL)
 
     Parser.add_option("-c", "--create", action="store", type="string", 
dest="Create_Distribution_Package_File",
@@ -228,12 +228,14 @@ def Main():
             RunModule = MkPkg.Main
 
         elif Opt.PackFileToInstall:
-            if not Opt.PackFileToInstall.endswith('.dist'):
-                Logger.Error("InstallPkg", FILE_TYPE_MISMATCH, 
ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToInstall)
-
-            AbsPath = GetFullPathDist(Opt.PackFileToInstall, WorkspaceDir)
-            if not AbsPath:
-                Logger.Error("InstallPkg", FILE_NOT_FOUND, 
ST.ERR_INSTALL_DIST_NOT_FOUND % Opt.PackFileToInstall)
+            AbsPath = []
+            for Item in Opt.PackFileToInstall:
+                if not Item.endswith('.dist'):
+                    Logger.Error("InstallPkg", FILE_TYPE_MISMATCH, 
ExtraData=ST.ERR_DIST_EXT_ERROR % Item)
+
+                AbsPath.append(GetFullPathDist(Item, WorkspaceDir))
+                if not AbsPath:
+                    Logger.Error("InstallPkg", FILE_NOT_FOUND, 
ST.ERR_INSTALL_DIST_NOT_FOUND % Item)
 
             Opt.PackFileToInstall = AbsPath
             setattr(Opt, 'PackageFile', Opt.PackFileToInstall)
-- 
2.7.2.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to