From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.43; helo=mga05.intel.com; envelope-from=bob.c.feng@intel.com; receiver=edk2-devel@lists.01.org Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 640D9211935BD for ; Tue, 20 Nov 2018 23:22:23 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Nov 2018 23:22:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,260,1539673200"; d="scan'208";a="88074097" Received: from fmsmsx107.amr.corp.intel.com ([10.18.124.205]) by fmsmga008.fm.intel.com with ESMTP; 20 Nov 2018 23:22:23 -0800 Received: from shsmsx104.ccr.corp.intel.com (10.239.4.70) by fmsmsx107.amr.corp.intel.com (10.18.124.205) with Microsoft SMTP Server (TLS) id 14.3.408.0; Tue, 20 Nov 2018 23:22:23 -0800 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.102]) by SHSMSX104.ccr.corp.intel.com ([169.254.5.117]) with mapi id 14.03.0415.000; Wed, 21 Nov 2018 15:22:20 +0800 From: "Feng, Bob C" To: "Zhao, ZhiqiangX" , "edk2-devel@lists.01.org" CC: "Gao, Liming" , "Carsey, Jaben" , "Feng, Bob C" Thread-Topic: [PATCH] BaseTools: AutoGen and GenFds share the parser data. Thread-Index: AQHUgWQMK2TntwAGHk66DfpFXEHcXqVZzjdg Date: Wed, 21 Nov 2018 07:22:19 +0000 Message-ID: <08650203BA1BD64D8AD9B6D5D74A85D15FFFFF1E@SHSMSX101.ccr.corp.intel.com> References: <20181121063253.49824-1-zhiqiangx.zhao@intel.com> In-Reply-To: <20181121063253.49824-1-zhiqiangx.zhao@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiYzJlY2IzMGQtZmJmMi00ODM0LWFlYzgtYWJlODNmYjYyODM5IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiem5SK2NnSm1TXC8wN0U1djZ6XC9pZU1HOExzcTdLRWVma0ZTRGt1eElncGFrU0JGTTFvdVwvUExrVEVIM2pQcGtSVSJ9 x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.0.400.15 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH] BaseTools: AutoGen and GenFds share the parser data. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Nov 2018 07:22:24 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Zhiqiang, Could you extract the common part of your new API and the original main() f= unction into one function. And call it in both your new API and main() ? Thanks, Bob -----Original Message----- From: Zhao, ZhiqiangX=20 Sent: Wednesday, November 21, 2018 2:33 PM To: edk2-devel@lists.01.org Cc: Zhao, ZhiqiangX ; Gao, Liming ; Carsey; Carsey, Jaben ; Feng, Bob C Subject: [PATCH] BaseTools: AutoGen and GenFds share the parser data. https://bugzilla.tianocore.org/show_bug.cgi?id=3D1288 Currently, AutoGen and GenFds run in different python interpreters. The par= ser are duplicated. This patch is going to create new API for GenFds and ha= ve the build to call that API instead of executing GenFds.py. As such, the = GenFds and build can share the parser data. This patch is expected to save the time of GenFds about 2~3 seconds. More details will be logged in BZ. This is the summary measure data generated from python cProfile for buildin= g Ovmf. Currently: 8379147 function calls (8135450 primitive calls) in 12.580 seconds After applying this patch: 3428712 function calls (3418881 primitive calls) in 8.944 seconds Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: ZhiqiangX Zhao Cc: Liming Gao Cc: Carsey, Jaben Cc: Bob Feng --- BaseTools/Source/Python/AutoGen/AutoGen.py | 4 + BaseTools/Source/Python/GenFds/GenFds.py | 266 +++++++++++++++++++++++++= +++- BaseTools/Source/Python/build/build.py | 4 +- 3 files changed, 271 insertions(+), 3 deletions(-) diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/= Python/AutoGen/AutoGen.py index f3560bfc78..10ce7eb962 100644 --- a/BaseTools/Source/Python/AutoGen/AutoGen.py +++ b/BaseTools/Source/Python/AutoGen/AutoGen.py @@ -935,6 +935,10 @@ class WorkspaceAutoGen(AutoGen): def GenFdsCommand(self): return (GenMake.TopLevelMakefile(self)._TEMPLATE_.Replace(GenMake.= TopLevelMakefile(self)._TemplateDict)).strip() =20 + @property + def GenFdsCommandDict(self): + return GenMake.TopLevelMakefile(self)._TemplateDict + ## Create makefile for the platform and modules in it # # @param CreateDepsMakeFile Flag indicating if the makefil= e for diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Py= thon/GenFds/GenFds.py index 0c8091b798..96158568b0 100644 --- a/BaseTools/Source/Python/GenFds/GenFds.py +++ b/BaseTools/Source/Python/GenFds/GenFds.py @@ -35,7 +35,7 @@ from Common.Misc import DirCache, PathClass, GuidStructur= eStringToGuidString from Common.Misc import SaveFileOnChange, ClearDuplica= tedInf from Common.BuildVersion import gBUILD_VERSION from Common.Multipl= eWorkspace import MultipleWorkspace as mws -from Common.BuildToolError impo= rt FatalError, GENFDS_ERROR, CODE_ERROR, FORMAT_INVALID, RESOURCE_NOT_AVAIL= ABLE, FILE_NOT_FOUND, OPTION_MISSING, FORMAT_NOT_SUPPORTED,OPTION_VALUE_INV= ALID +from Common.BuildToolError import FatalError, GENFDS_ERROR, CODE_ERROR,=20 +FORMAT_INVALID, RESOURCE_NOT_AVAILABLE, FILE_NOT_FOUND, OPTION_MISSING,=20 +FORMAT_NOT_SUPPORTED, OPTION_VALUE_INVALID, PARAMETER_INVALID from Workspace.WorkspaceDatabase import WorkspaceDatabase =20 from .FdfParser import FdfParser, Warning @@ -716,6 +716,270 @@ class GenF= ds(object): os.remove(GuidXRefFileName) GuidXRefFile.close() =20 + @staticmethod + def GenFdsApi(FdsCommandDict, WorkSpaceDataBase): + global Workspace + Workspace =3D os.environ.get('WORKSPACE') + ArchList =3D None + ReturnCode =3D 0 + try: + if not os.path.exists(Workspace): + EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is= invalid", + ExtraData=3D"Please use '-w' switch to pas= s it or set the WORKSPACE environment variable.") + else: + Workspace =3D os.path.normcase(Workspace) + GenFdsGlobalVariable.WorkSpaceDir =3D Workspace + if 'EDK_SOURCE' in os.environ: + GenFdsGlobalVariable.EdkSourceDir =3D os.path.normcase= (os.environ['EDK_SOURCE']) + os.chdir(GenFdsGlobalVariable.WorkSpaceDir) + + # set multiple workspace + PackagesPath =3D os.getenv("PACKAGES_PATH") + mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath) + + if FdsCommandDict["fdf_file"]: + FdfFilename =3D FdsCommandDict["fdf_file"][0] + FdfFilename =3D=20 + GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename.Path) + + if FdfFilename[0:2] =3D=3D '..': + FdfFilename =3D os.path.realpath(FdfFilename) + if not os.path.isabs(FdfFilename): + FdfFilename =3D mws.join(GenFdsGlobalVariable.WorkSpac= eDir, FdfFilename) + if not os.path.exists(FdfFilename): + EdkLogger.error("GenFds", FILE_NOT_FOUND,=20 + ExtraData=3DFdfFilename) + + GenFdsGlobalVariable.FdfFile =3D FdfFilename + GenFdsGlobalVariable.FdfFileTimeStamp =3D os.path.getmtime= (FdfFilename) + else: + EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF=20 + filename") + + if FdsCommandDict["build_target"]: + GenFdsGlobalVariable.TargetName =3D=20 + FdsCommandDict["build_target"] + + if FdsCommandDict["toolchain_tag"]: + GenFdsGlobalVariable.ToolChainTag =3D=20 + FdsCommandDict["toolchain_tag"] + + if FdsCommandDict["active_platform"]: + ActivePlatform =3D FdsCommandDict["active_platform"] + ActivePlatform =3D=20 + GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform) + + if ActivePlatform[0:2] =3D=3D '..': + ActivePlatform =3D os.path.realpath(ActivePlatform) + + if not os.path.isabs (ActivePlatform): + ActivePlatform =3D=20 + mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform) + + if not os.path.exists(ActivePlatform): + EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatf= orm doesn't exist!") + else: + EdkLogger.error("GenFds", OPTION_MISSING, "Missing=20 + active platform") + + GenFdsGlobalVariable.ActivePlatform =3D=20 + PathClass(NormPath(ActivePlatform)) + + if FdsCommandDict["conf_directory"]: + # Get alternate Conf location, if it is absolute, then jus= t use the absolute directory name + ConfDirectoryPath =3D os.path.normpath(FdsCommandDict["con= f_directory"]) + if ConfDirectoryPath.startswith('"'): + ConfDirectoryPath =3D ConfDirectoryPath[1:] + if ConfDirectoryPath.endswith('"'): + ConfDirectoryPath =3D ConfDirectoryPath[:-1] + if not os.path.isabs(ConfDirectoryPath): + # Since alternate directory name is not absolute, the = alternate directory is located within the WORKSPACE + # This also handles someone specifying the Conf direct= ory in the workspace. Using --conf=3DConf + ConfDirectoryPath =3D os.path.join(GenFdsGlobalVariabl= e.WorkSpaceDir, ConfDirectoryPath) + else: + if "CONF_PATH" in os.environ: + ConfDirectoryPath =3D os.path.normcase(os.environ["CON= F_PATH"]) + else: + # Get standard WORKSPACE/Conf, use the absolute path t= o the WORKSPACE/Conf + ConfDirectoryPath =3D mws.join(GenFdsGlobalVariable.Wo= rkSpaceDir, 'Conf') + GenFdsGlobalVariable.ConfDir =3D ConfDirectoryPath + if not GlobalData.gConfDirectory: + GlobalData.gConfDirectory =3D GenFdsGlobalVariable.ConfDir + BuildConfigurationFile =3D os.path.normpath(os.path.join(ConfD= irectoryPath, "target.txt")) + if os.path.isfile(BuildConfigurationFile) =3D=3D True: + TargetTxt =3D TargetTxtClassObject() + TargetTxt.LoadTargetTxtFile(BuildConfigurationFile) + # if no build target given in command line, get it from ta= rget.txt + if not GenFdsGlobalVariable.TargetName: + BuildTargetList =3D TargetTxt.TargetTxtDictionary[TAB_= TAT_DEFINES_TARGET] + if len(BuildTargetList) !=3D 1: + EdkLogger.error("GenFds", OPTION_VALUE_INVALID, Ex= traData=3D"Only allows one instance for Target.") + GenFdsGlobalVariable.TargetName =3D=20 + BuildTargetList[0] + + # if no tool chain given in command line, get it from targ= et.txt + if not GenFdsGlobalVariable.ToolChainTag: + ToolChainList =3D TargetTxt.TargetTxtDictionary[TAB_TA= T_DEFINES_TOOL_CHAIN_TAG] + if ToolChainList is None or len(ToolChainList) =3D=3D = 0: + EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, = ExtraData=3D"No toolchain given. Don't know how to build.") + if len(ToolChainList) !=3D 1: + EdkLogger.error("GenFds", OPTION_VALUE_INVALID, Ex= traData=3D"Only allows one instance for ToolChain.") + GenFdsGlobalVariable.ToolChainTag =3D ToolChainList[0] + else: + EdkLogger.error("GenFds", FILE_NOT_FOUND,=20 + ExtraData=3DBuildConfigurationFile) + + if FdsCommandDict["macro"]: + for Pair in FdsCommandDict["macro"]: + if Pair.startswith('"'): + Pair =3D Pair[1:] + if Pair.endswith('"'): + Pair =3D Pair[:-1] + List =3D Pair.split('=3D') + if len(List) =3D=3D 2: + if not List[1].strip(): + EdkLogger.error("GenFds", OPTION_VALUE_INVALID= , ExtraData=3D"No Value given for Macro %s" %List[0]) + if List[0].strip() =3D=3D "EFI_SOURCE": + GlobalData.gEfiSource =3D List[1].strip() + GlobalData.gGlobalDefines["EFI_SOURCE"] =3D Gl= obalData.gEfiSource + continue + elif List[0].strip() =3D=3D "EDK_SOURCE": + GlobalData.gEdkSource =3D List[1].strip() + GlobalData.gGlobalDefines["EDK_SOURCE"] =3D Gl= obalData.gEdkSource + continue + elif List[0].strip() in ["WORKSPACE", "TARGET", "T= OOLCHAIN"]: + GlobalData.gGlobalDefines[List[0].strip()] =3D= List[1].strip() + else: + GlobalData.gCommandLineDefines[List[0].strip()= ] =3D List[1].strip() + else: + GlobalData.gCommandLineDefines[List[0].strip()] = =3D "TRUE" + os.environ["WORKSPACE"] =3D Workspace + + # Use the -t and -b option as gGlobalDefines's TOOLCHAIN and T= ARGET if they are not defined + if "TARGET" not in GlobalData.gGlobalDefines: + GlobalData.gGlobalDefines["TARGET"] =3D GenFdsGlobalVariab= le.TargetName + if "TOOLCHAIN" not in GlobalData.gGlobalDefines: + GlobalData.gGlobalDefines["TOOLCHAIN"] =3D GenFdsGlobalVar= iable.ToolChainTag + if "TOOL_CHAIN_TAG" not in GlobalData.gGlobalDefines: + GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] =3D=20 + GenFdsGlobalVariable.ToolChainTag + + """call Workspace build create database""" + BuildWorkSpace =3D WorkSpaceDataBase + + # + # Get files real name in workspace dir + # + GlobalData.gAllFiles =3D DirCache(Workspace) + GlobalData.gWorkspace =3D Workspace + + if FdsCommandDict["build_architecture_list"]: + ArchList =3D FdsCommandDict["build_architecture_list"].spl= it(',') + else: + ArchList =3D=20 + BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform,=20 + TAB_COMMON, FdsCommandDict["build_target"],=20 + FdsCommandDict["toolchain_tag"]].SupArchList + + TargetArchList =3D set(BuildWorkSpace.BuildObject[GenFdsGlobal= Variable.ActivePlatform, TAB_COMMON, FdsCommandDict["build_target"], FdsCom= mandDict["toolchain_tag"]].SupArchList) & set(ArchList) + if len(TargetArchList) =3D=3D 0: + EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s=20 + not in platform supported ARCH %s" % (str(ArchList),=20 + str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform,=20 + TAB_COMMON].SupArchList))) + + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirFromDscDict[Arch] =3D=20 + NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatfor + m, Arch, FdsCommandDict["build_target"],=20 + FdsCommandDict["toolchain_tag"]].OutputDirectory) + + # assign platform name based on last entry in ArchList + GenFdsGlobalVariable.PlatformName =3D=20 + BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform,=20 + ArchList[-1], FdsCommandDict["build_target"],=20 + FdsCommandDict["toolchain_tag"]].PlatformName + + if FdsCommandDict["platform_build_directory"]: + OutputDirFromCommandLine =3D GenFdsGlobalVariable.ReplaceW= orkspaceMacro(FdsCommandDict["platform_build_directory"]) + if not os.path.isabs (OutputDirFromCommandLine): + OutputDirFromCommandLine =3D os.path.join(GenFdsGlobal= Variable.WorkSpaceDir, OutputDirFromCommandLine) + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirDict[Arch] =3D OutputDir= FromCommandLine + else: + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirDict[Arch] =3D=20 + os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch],=20 + GenFdsGlobalVariable.TargetName + '_' +=20 + GenFdsGlobalVariable.ToolChainTag) + + for Key in GenFdsGlobalVariable.OutputDirDict: + OutputDir =3D GenFdsGlobalVariable.OutputDirDict[Key] + if OutputDir[0:2] =3D=3D '..': + OutputDir =3D os.path.realpath(OutputDir) + + if OutputDir[1] !=3D ':': + OutputDir =3D os.path.join=20 + (GenFdsGlobalVariable.WorkSpaceDir, OutputDir) + + if not os.path.exists(OutputDir): + EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=3D= OutputDir) + GenFdsGlobalVariable.OutputDirDict[Key] =3D OutputDir + + """ Parse Fdf file, has to place after build Workspace as FDF = may contain macros from DSC file """ + FdfParserObj =3D GlobalData.gFdfParser + + if FdfParserObj.CycleReferenceCheck(): + EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle=20 + Reference Detected in FDF file") + + if FdsCommandDict["fd"]: + if FdsCommandDict["fd"][0].upper() in FdfParserObj.Profile= .FdDict: + GenFds.OnlyGenerateThisFd =3D FdsCommandDict["fd"][0] + else: + EdkLogger.error("GenFds", OPTION_VALUE_INVALID, + "No such an FD in FDF file: %s" %=20 + FdsCommandDict["fd"][0]) + + if FdsCommandDict["fv"]: + if FdsCommandDict["fv"][0].upper() in FdfParserObj.Profile= .FvDict: + GenFds.OnlyGenerateThisFv =3D FdsCommandDict["fv"][0] + else: + EdkLogger.error("GenFds", OPTION_VALUE_INVALID, + "No such an FV in FDF file: %s" %=20 + FdsCommandDict["fv"][0]) + + if FdsCommandDict["cap"]: + if FdsCommandDict["cap"][0].upper() in FdfParserObj.Profil= e.CapsuleDict: + GenFds.OnlyGenerateThisCap =3D FdsCommandDict["cap"][0= ] + else: + EdkLogger.error("GenFds", OPTION_VALUE_INVALID, + "No such a Capsule in FDF file: %s"=20 + % FdsCommandDict["cap"][0]) + + GenFdsGlobalVariable.WorkSpace =3D BuildWorkSpace + if ArchList: + GenFdsGlobalVariable.ArchList =3D ArchList + + # Dsc Build Data will handle Pcd Settings from CommandLine. + + """Modify images from build output if the feature of loading d= river at fixed address is on.""" + if GenFdsGlobalVariable.FixedLoadAddress: + GenFds.PreprocessImage(BuildWorkSpace,=20 + GenFdsGlobalVariable.ActivePlatform) + + # Record the FV Region info that may specific in the FD + if FdfParserObj.Profile.FvDict and FdfParserObj.Profile.FdDict= : + for FvObj in FdfParserObj.Profile.FvDict.values(): + for FdObj in FdfParserObj.Profile.FdDict.values(): + for RegionObj in FdObj.RegionList: + if RegionObj.RegionType !=3D BINARY_FILE_TYPE_= FV: + continue + for RegionData in RegionObj.RegionDataList: + if FvObj.UiFvName.upper() =3D=3D RegionDat= a.upper(): + if FvObj.FvRegionInFD: + if FvObj.FvRegionInFD !=3D RegionO= bj.Size: + EdkLogger.error("GenFds", FORM= AT_INVALID, "The FV %s's region is specified in multiple FD with different = value." %FvObj.UiFvName) + else: + FvObj.FvRegionInFD =3D RegionObj.S= ize + =20 + RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, FvObj) + + """Call GenFds""" + GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList) + + """Generate GUID cross reference file""" + GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList,=20 + FdfParserObj) + + """Display FV space info.""" + GenFds.DisplayFvSpaceInfo(FdfParserObj) + + except Warning as X: + EdkLogger.error(X.ToolName, FORMAT_INVALID, File=3DX.FileName,= Line=3DX.LineNumber, ExtraData=3DX.Message, RaiseError=3DFalse) + ReturnCode =3D FORMAT_INVALID + except FatalError as X: + ReturnCode =3D X.args[0] + except: + import traceback + EdkLogger.error( + "\nPython", + CODE_ERROR, + "Tools code failure", + ExtraData=3D"Please send email to edk2-devel@lists= .01.org for help, attaching following call stack trace!\n", + RaiseError=3DFalse + ) + EdkLogger.quiet(traceback.format_exc()) + ReturnCode =3D CODE_ERROR + finally: + ClearDuplicatedInf() + return ReturnCode + if __name__ =3D=3D '__main__': r =3D main() ## 0-127 is a safe return range, and 1 is a standard default error dif= f --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/= build/build.py index d74082fc26..71940b37e3 100644 --- a/BaseTools/Source/Python/build/build.py +++ b/BaseTools/Source/Python/build/build.py @@ -1392,7 +1392,7 @@ class Build(): =20 # genfds if Target =3D=3D 'fds': - LaunchCommand(AutoGenObject.GenFdsCommand, AutoGenObject.MakeF= ileDir) + GenFds.GenFdsApi(AutoGenObject.GenFdsCommandDict, self.Db) return True =20 # run @@ -2136,7 +2136,7 @@ class Build(): # Generate FD image if there's a FDF file found # GenFdsStart =3D time.time() - LaunchCommand(Wa.GenFdsCommand, os.getcwd()) + GenFds.GenFdsApi(Wa.GenFdsCommandDict, self.Db) =20 # # Create MAP file for all platform FVs after GenFd= s. -- 2.14.1.windows.1