X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FGenFds%2FGenFds.py;h=21ae9c4d4c8f2a6c051b2c5e77faefde878a497b;hb=2e351cbe8e190271b3716284fc1076551d005472;hp=ed1bd33fdbb3246c23f221aee88d53d421906b42;hpb=2e300969aeff5a863098242ebd95b7d653893262;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py index ed1bd33fdb..21ae9c4d4c 100644 --- a/BaseTools/Source/Python/GenFds/GenFds.py +++ b/BaseTools/Source/Python/GenFds/GenFds.py @@ -1,49 +1,42 @@ ## @file # generate flash image # -# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2019, 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. +# SPDX-License-Identifier: BSD-2-Clause-Patent # ## # Import Modules # +from __future__ import print_function +from __future__ import absolute_import +from re import compile from optparse import OptionParser -import sys -import Common.LongFilePathOs as os -import linecache -from . import FdfParser -import Common.BuildToolError as BuildToolError -from .GenFdsGlobalVariable import GenFdsGlobalVariable -from Workspace.WorkspaceDatabase import WorkspaceDatabase -from Workspace.BuildClassObject import PcdClassObject -from . import RuleComplexFile -from .EfiSection import EfiSection +from sys import exit +from glob import glob +from struct import unpack +from linecache import getlines from io import BytesIO -from io import StringIO -import Common.TargetTxtClassObject as TargetTxtClassObject -import Common.ToolDefClassObject as ToolDefClassObject + +import Common.LongFilePathOs as os +from Common.TargetTxtClassObject import TargetTxtClassObject from Common.DataType import * import Common.GlobalData as GlobalData from Common import EdkLogger -from Common.StringUtils import * -from Common.Misc import DirCache, PathClass -from Common.Misc import SaveFileOnChange -from Common.Misc import ClearDuplicatedInf -from Common.Misc import GuidStructureStringToGuidString +from Common.StringUtils import NormPath +from Common.Misc import DirCache, PathClass, GuidStructureStringToGuidString +from Common.Misc import SaveFileOnChange, ClearDuplicatedInf from Common.BuildVersion import gBUILD_VERSION from Common.MultipleWorkspace import MultipleWorkspace as mws -from . import FfsFileStatement -import glob -from struct import unpack -from Common.GlobalData import gGuidPattern +from Common.BuildToolError import FatalError, GENFDS_ERROR, CODE_ERROR, FORMAT_INVALID, RESOURCE_NOT_AVAILABLE, FILE_NOT_FOUND, OPTION_MISSING, FORMAT_NOT_SUPPORTED, OPTION_VALUE_INVALID, PARAMETER_INVALID +from Workspace.WorkspaceDatabase import WorkspaceDatabase + +from .FdfParser import FdfParser, Warning +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from .FfsFileStatement import FileStatement +import Common.DataType as DataType +from struct import Struct ## Version and Copyright versionNumber = "1.0" + ' ' + gBUILD_VERSION @@ -62,43 +55,90 @@ __copyright__ = "Copyright (c) 2007 - 2018, Intel Corporation All rights reserv def main(): global Options Options = myOptionParser() - + EdkLogger.Initialize() + return GenFdsApi(OptionsToCommandDict(Options)) + +def resetFdsGlobalVariable(): + GenFdsGlobalVariable.FvDir = '' + GenFdsGlobalVariable.OutputDirDict = {} + GenFdsGlobalVariable.BinDir = '' + # will be FvDir + os.sep + 'Ffs' + GenFdsGlobalVariable.FfsDir = '' + GenFdsGlobalVariable.FdfParser = None + GenFdsGlobalVariable.LibDir = '' + GenFdsGlobalVariable.WorkSpace = None + GenFdsGlobalVariable.WorkSpaceDir = '' + GenFdsGlobalVariable.ConfDir = '' + GenFdsGlobalVariable.OutputDirFromDscDict = {} + GenFdsGlobalVariable.TargetName = '' + GenFdsGlobalVariable.ToolChainTag = '' + GenFdsGlobalVariable.RuleDict = {} + GenFdsGlobalVariable.ArchList = None + GenFdsGlobalVariable.ActivePlatform = None + GenFdsGlobalVariable.FvAddressFileName = '' + GenFdsGlobalVariable.VerboseMode = False + GenFdsGlobalVariable.DebugLevel = -1 + GenFdsGlobalVariable.SharpCounter = 0 + GenFdsGlobalVariable.SharpNumberPerLine = 40 + GenFdsGlobalVariable.FdfFile = '' + GenFdsGlobalVariable.FdfFileTimeStamp = 0 + GenFdsGlobalVariable.FixedLoadAddress = False + GenFdsGlobalVariable.PlatformName = '' + + GenFdsGlobalVariable.BuildRuleFamily = DataType.TAB_COMPILER_MSFT + GenFdsGlobalVariable.ToolChainFamily = DataType.TAB_COMPILER_MSFT + GenFdsGlobalVariable.__BuildRuleDatabase = None + GenFdsGlobalVariable.GuidToolDefinition = {} + GenFdsGlobalVariable.FfsCmdDict = {} + GenFdsGlobalVariable.SecCmdList = [] + GenFdsGlobalVariable.CopyList = [] + GenFdsGlobalVariable.ModuleFile = '' + GenFdsGlobalVariable.EnableGenfdsMultiThread = False + + GenFdsGlobalVariable.LargeFileInFvFlags = [] + GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A' + GenFdsGlobalVariable.LARGE_FILE_SIZE = 0x1000000 + + GenFdsGlobalVariable.SectionHeader = Struct("3B 1B") + + # FvName, FdName, CapName in FDF, Image file name + GenFdsGlobalVariable.ImageBinDict = {} + +def GenFdsApi(FdsCommandDict, WorkSpaceDataBase=None): global Workspace Workspace = "" ArchList = None ReturnCode = 0 + resetFdsGlobalVariable() - EdkLogger.Initialize() try: - if Options.verbose is not None: + if FdsCommandDict.get("verbose"): EdkLogger.SetLevel(EdkLogger.VERBOSE) GenFdsGlobalVariable.VerboseMode = True - if Options.FixedAddress is not None: + if FdsCommandDict.get("FixedAddress"): GenFdsGlobalVariable.FixedLoadAddress = True - if Options.quiet is not None: + if FdsCommandDict.get("quiet"): EdkLogger.SetLevel(EdkLogger.QUIET) - if Options.debug is not None: - EdkLogger.SetLevel(Options.debug + 1) - GenFdsGlobalVariable.DebugLevel = Options.debug + if FdsCommandDict.get("debug"): + EdkLogger.SetLevel(FdsCommandDict.get("debug") + 1) + GenFdsGlobalVariable.DebugLevel = FdsCommandDict.get("debug") else: EdkLogger.SetLevel(EdkLogger.INFO) - if (Options.Workspace is None): + if not FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE')): EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined", ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.") - elif not os.path.exists(Options.Workspace): + elif not os.path.exists(FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE'))): EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid", ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.") else: - Workspace = os.path.normcase(Options.Workspace) + Workspace = os.path.normcase(FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE'))) GenFdsGlobalVariable.WorkSpaceDir = Workspace - if 'EDK_SOURCE' in os.environ: - GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE']) - if (Options.debug): + if FdsCommandDict.get("debug"): GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace) - if Options.GenfdsMultiThread: + if FdsCommandDict.get("GenfdsMultiThread"): GenFdsGlobalVariable.EnableGenfdsMultiThread = True os.chdir(GenFdsGlobalVariable.WorkSpaceDir) @@ -106,8 +146,8 @@ def main(): PackagesPath = os.getenv("PACKAGES_PATH") mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath) - if (Options.filename): - FdfFilename = Options.filename + if FdsCommandDict.get("fdf_file"): + FdfFilename = FdsCommandDict.get("fdf_file")[0].Path FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename) if FdfFilename[0:2] == '..': @@ -122,14 +162,14 @@ def main(): else: EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename") - if (Options.BuildTarget): - GenFdsGlobalVariable.TargetName = Options.BuildTarget + if FdsCommandDict.get("build_target"): + GenFdsGlobalVariable.TargetName = FdsCommandDict.get("build_target") - if (Options.ToolChain): - GenFdsGlobalVariable.ToolChainTag = Options.ToolChain + if FdsCommandDict.get("toolchain_tag"): + GenFdsGlobalVariable.ToolChainTag = FdsCommandDict.get("toolchain_tag") - if (Options.activePlatform): - ActivePlatform = Options.activePlatform + if FdsCommandDict.get("active_platform"): + ActivePlatform = FdsCommandDict.get("active_platform") ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform) if ActivePlatform[0:2] == '..': @@ -138,17 +178,16 @@ def main(): if not os.path.isabs (ActivePlatform): ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform) - if not os.path.exists(ActivePlatform) : + if not os.path.exists(ActivePlatform): EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!") else: EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform") - GlobalData.BuildOptionPcd = Options.OptionPcd if Options.OptionPcd else {} GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform)) - if (Options.ConfDirectory): + if FdsCommandDict.get("conf_directory"): # Get alternate Conf location, if it is absolute, then just use the absolute directory name - ConfDirectoryPath = os.path.normpath(Options.ConfDirectory) + ConfDirectoryPath = os.path.normpath(FdsCommandDict.get("conf_directory")) if ConfDirectoryPath.startswith('"'): ConfDirectoryPath = ConfDirectoryPath[1:] if ConfDirectoryPath.endswith('"'): @@ -168,18 +207,18 @@ def main(): GlobalData.gConfDirectory = GenFdsGlobalVariable.ConfDir BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt")) if os.path.isfile(BuildConfigurationFile) == True: - TargetTxt = TargetTxtClassObject.TargetTxtClassObject() + TargetTxt = TargetTxtClassObject() TargetTxt.LoadTargetTxtFile(BuildConfigurationFile) # if no build target given in command line, get it from target.txt if not GenFdsGlobalVariable.TargetName: - BuildTargetList = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET] + BuildTargetList = TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_TARGET] if len(BuildTargetList) != 1: EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for Target.") GenFdsGlobalVariable.TargetName = BuildTargetList[0] # if no tool chain given in command line, get it from target.txt if not GenFdsGlobalVariable.ToolChainTag: - ToolChainList = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG] + ToolChainList = TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_TOOL_CHAIN_TAG] if ToolChainList is None or len(ToolChainList) == 0: EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.") if len(ToolChainList) != 1: @@ -189,10 +228,10 @@ def main(): EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile) #Set global flag for build mode - GlobalData.gIgnoreSource = Options.IgnoreSources + GlobalData.gIgnoreSource = FdsCommandDict.get("IgnoreSources") - if Options.Macros: - for Pair in Options.Macros: + if FdsCommandDict.get("macro"): + for Pair in FdsCommandDict.get("macro"): if Pair.startswith('"'): Pair = Pair[1:] if Pair.endswith('"'): @@ -201,15 +240,7 @@ def main(): if len(List) == 2: if not List[1].strip(): EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="No Value given for Macro %s" %List[0]) - if List[0].strip() == "EFI_SOURCE": - GlobalData.gEfiSource = List[1].strip() - GlobalData.gGlobalDefines["EFI_SOURCE"] = GlobalData.gEfiSource - continue - elif List[0].strip() == "EDK_SOURCE": - GlobalData.gEdkSource = List[1].strip() - GlobalData.gGlobalDefines["EDK_SOURCE"] = GlobalData.gEdkSource - continue - elif List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]: + if List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]: GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip() else: GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip() @@ -227,31 +258,34 @@ def main(): """call Workspace build create database""" GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath)) - BuildWorkSpace = WorkspaceDatabase(GlobalData.gDatabasePath) - BuildWorkSpace.InitDatabase() + if WorkSpaceDataBase: + BuildWorkSpace = WorkSpaceDataBase + else: + BuildWorkSpace = WorkspaceDatabase() # # Get files real name in workspace dir # GlobalData.gAllFiles = DirCache(Workspace) GlobalData.gWorkspace = Workspace - if (Options.archList) : - ArchList = Options.archList.split(',') + if FdsCommandDict.get("build_architecture_list"): + ArchList = FdsCommandDict.get("build_architecture_list").split(',') else: -# EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH") - ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, Options.BuildTarget, Options.ToolChain].SupArchList + ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList - TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, Options.BuildTarget, Options.ToolChain].SupArchList) & set(ArchList) + TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList) & set(ArchList) if len(TargetArchList) == 0: EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON].SupArchList))) for Arch in ArchList: - GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].OutputDirectory) - GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].PlatformName + GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].OutputDirectory) + + # assign platform name based on last entry in ArchList + GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, ArchList[-1], FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].PlatformName - if (Options.outputDir): - OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir) + if FdsCommandDict.get("platform_build_directory"): + OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdsCommandDict.get("platform_build_directory")) if not os.path.isabs (OutputDirFromCommandLine): OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine) for Arch in ArchList: @@ -273,35 +307,38 @@ def main(): GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """ - FdfParserObj = FdfParser.FdfParser(FdfFilename) - FdfParserObj.ParseFile() + if WorkSpaceDataBase: + FdfParserObj = GlobalData.gFdfParser + else: + FdfParserObj = FdfParser(FdfFilename) + FdfParserObj.ParseFile() if FdfParserObj.CycleReferenceCheck(): EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file") - if (Options.uiFdName) : - if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict: - GenFds.OnlyGenerateThisFd = Options.uiFdName + if FdsCommandDict.get("fd"): + if FdsCommandDict.get("fd")[0].upper() in FdfParserObj.Profile.FdDict: + GenFds.OnlyGenerateThisFd = FdsCommandDict.get("fd")[0] else: EdkLogger.error("GenFds", OPTION_VALUE_INVALID, - "No such an FD in FDF file: %s" % Options.uiFdName) + "No such an FD in FDF file: %s" % FdsCommandDict.get("fd")[0]) - if (Options.uiFvName) : - if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict: - GenFds.OnlyGenerateThisFv = Options.uiFvName + if FdsCommandDict.get("fv"): + if FdsCommandDict.get("fv")[0].upper() in FdfParserObj.Profile.FvDict: + GenFds.OnlyGenerateThisFv = FdsCommandDict.get("fv")[0] else: EdkLogger.error("GenFds", OPTION_VALUE_INVALID, - "No such an FV in FDF file: %s" % Options.uiFvName) + "No such an FV in FDF file: %s" % FdsCommandDict.get("fv")[0]) - if (Options.uiCapName) : - if Options.uiCapName.upper() in FdfParserObj.Profile.CapsuleDict: - GenFds.OnlyGenerateThisCap = Options.uiCapName + if FdsCommandDict.get("cap"): + if FdsCommandDict.get("cap")[0].upper() in FdfParserObj.Profile.CapsuleDict: + GenFds.OnlyGenerateThisCap = FdsCommandDict.get("cap")[0] else: EdkLogger.error("GenFds", OPTION_VALUE_INVALID, - "No such a Capsule in FDF file: %s" % Options.uiCapName) + "No such a Capsule in FDF file: %s" % FdsCommandDict.get("cap")[0]) GenFdsGlobalVariable.WorkSpace = BuildWorkSpace - if ArchList is not None: + if ArchList: GenFdsGlobalVariable.ArchList = ArchList # Dsc Build Data will handle Pcd Settings from CommandLine. @@ -312,15 +349,15 @@ def main(): # Record the FV Region info that may specific in the FD if FdfParserObj.Profile.FvDict and FdfParserObj.Profile.FdDict: - for Fv in FdfParserObj.Profile.FvDict: - FvObj = FdfParserObj.Profile.FvDict[Fv] - for Fd in FdfParserObj.Profile.FdDict: - FdObj = FdfParserObj.Profile.FdDict[Fd] + for FvObj in FdfParserObj.Profile.FvDict.values(): + for FdObj in FdfParserObj.Profile.FdDict.values(): for RegionObj in FdObj.RegionList: if RegionObj.RegionType != BINARY_FILE_TYPE_FV: continue for RegionData in RegionObj.RegionDataList: if FvObj.UiFvName.upper() == RegionData.upper(): + if not FvObj.BaseAddress: + FvObj.BaseAddress = '0x%x' % (int(FdObj.BaseAddress, 0) + RegionObj.Offset) if FvObj.FvRegionInFD: if FvObj.FvRegionInFD != RegionObj.Size: EdkLogger.error("GenFds", FORMAT_INVALID, "The FV %s's region is specified in multiple FD with different value." %FvObj.UiFvName) @@ -337,11 +374,11 @@ def main(): """Display FV space info.""" GenFds.DisplayFvSpaceInfo(FdfParserObj) - except FdfParser.Warning as X: + except Warning as X: EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False) ReturnCode = FORMAT_INVALID except FatalError as X: - if Options.debug is not None: + if FdsCommandDict.get("debug") is not None: import traceback EdkLogger.quiet(traceback.format_exc()) ReturnCode = X.args[0] @@ -360,6 +397,30 @@ def main(): ClearDuplicatedInf() return ReturnCode +def OptionsToCommandDict(Options): + FdsCommandDict = {} + FdsCommandDict["verbose"] = Options.verbose + FdsCommandDict["FixedAddress"] = Options.FixedAddress + FdsCommandDict["quiet"] = Options.quiet + FdsCommandDict["debug"] = Options.debug + FdsCommandDict["Workspace"] = Options.Workspace + FdsCommandDict["GenfdsMultiThread"] = Options.GenfdsMultiThread + FdsCommandDict["fdf_file"] = [PathClass(Options.filename)] if Options.filename else [] + FdsCommandDict["build_target"] = Options.BuildTarget + FdsCommandDict["toolchain_tag"] = Options.ToolChain + FdsCommandDict["active_platform"] = Options.activePlatform + FdsCommandDict["OptionPcd"] = Options.OptionPcd + FdsCommandDict["conf_directory"] = Options.ConfDirectory + FdsCommandDict["IgnoreSources"] = Options.IgnoreSources + FdsCommandDict["macro"] = Options.Macros + FdsCommandDict["build_architecture_list"] = Options.archList + FdsCommandDict["platform_build_directory"] = Options.outputDir + FdsCommandDict["fd"] = [Options.uiFdName] if Options.uiFdName else [] + FdsCommandDict["fv"] = [Options.uiFvName] if Options.uiFvName else [] + FdsCommandDict["cap"] = [Options.uiCapName] if Options.uiCapName else [] + return FdsCommandDict + + gParamCheck = [] def SingleCheckCallback(option, opt_str, value, parser): if option not in gParamCheck: @@ -373,7 +434,6 @@ def SingleCheckCallback(option, opt_str, value, parser): # Using standard Python module optparse to parse command line option of this tool. # # @retval Opt A optparse.Values object containing the parsed options -# @retval Args Target of build command # def myOptionParser(): usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\"" @@ -403,7 +463,7 @@ def myOptionParser(): Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ") Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.") - (Options, args) = Parser.parse_args() + Options, _ = Parser.parse_args() return Options ## The class implementing the EDK2 flash image generation process @@ -413,7 +473,7 @@ def myOptionParser(): # 2. Call methods of Fd class to generate FD # 3. Call methods of Fv class to generate FV that not belong to FD # -class GenFds : +class GenFds(object): FdfParsef = None OnlyGenerateThisFd = None OnlyGenerateThisFv = None @@ -422,12 +482,13 @@ class GenFds : ## GenFd() # # @param OutputDir Output directory - # @param FdfParser FDF contents parser + # @param FdfParserObject FDF contents parser # @param Workspace The directory of workspace # @param ArchList The Arch list of platform # - def GenFd (OutputDir, FdfParser, WorkSpace, ArchList): - GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList) + @staticmethod + def GenFd (OutputDir, FdfParserObject, WorkSpace, ArchList): + GenFdsGlobalVariable.SetDir ('', FdfParserObject, WorkSpace, ArchList) GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!") if GenFds.OnlyGenerateThisCap is not None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict: @@ -469,9 +530,10 @@ class GenFds : GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!") for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values(): OptRomObj.AddToBuffer(None) + @staticmethod - def GenFfsMakefile(OutputDir, FdfParser, WorkSpace, ArchList, GlobalData): - GenFdsGlobalVariable.SetEnv(FdfParser, WorkSpace, ArchList, GlobalData) + def GenFfsMakefile(OutputDir, FdfParserObject, WorkSpace, ArchList, GlobalData): + GenFdsGlobalVariable.SetEnv(FdfParserObject, WorkSpace, ArchList, GlobalData) for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values(): FdObj.GenFd(Flag=True) @@ -489,6 +551,7 @@ class GenFds : # @param FvObj Whose block size to get # @retval int Block size value # + @staticmethod def GetFvBlockSize(FvObj): DefaultBlockSize = 0x1 FdObj = None @@ -523,16 +586,17 @@ class GenFds : # @param FvObj Whose block size to get # @retval None # - def DisplayFvSpaceInfo(FdfParser): + @staticmethod + def DisplayFvSpaceInfo(FdfParserObject): FvSpaceInfoList = [] MaxFvNameLength = 0 - for FvName in FdfParser.Profile.FvDict: + for FvName in FdfParserObject.Profile.FvDict: if len(FvName) > MaxFvNameLength: MaxFvNameLength = len(FvName) FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map') if os.path.exists(FvSpaceInfoFileName): - FileLinesList = linecache.getlines(FvSpaceInfoFileName) + FileLinesList = getlines(FvSpaceInfoFileName) TotalFound = False Total = '' UsedFound = False @@ -574,6 +638,7 @@ class GenFds : # @param DscFile modules from dsc file will be preprocessed # @retval None # + @staticmethod def PreprocessImage(BuildDb, DscFile): PcdDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds PcdValue = '' @@ -599,14 +664,15 @@ class GenFds : ModuleObj = BuildDb.BuildObject[Key, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] print(ModuleObj.BaseName + ' ' + ModuleObj.ModuleType) + @staticmethod def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj): GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref") - GuidXRefFile = StringIO('') + GuidXRefFile = [] PkgGuidDict = {} GuidDict = {} ModuleList = [] FileGuidList = [] - GuidPattern = gGuidPattern + VariableGuidSet = set() for Arch in ArchList: PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag) @@ -617,6 +683,8 @@ class GenFds : if Pcd.Type in [TAB_PCDS_DYNAMIC_HII, TAB_PCDS_DYNAMIC_EX_HII]: for SkuId in Pcd.SkuInfoList: Sku = Pcd.SkuInfoList[SkuId] + if Sku.VariableGuid in VariableGuidSet:continue + VariableGuidSet.add(Sku.VariableGuid) if Sku.VariableGuid and Sku.VariableGuid in PkgGuidDict.keys(): GuidDict[Sku.VariableGuid] = PkgGuidDict[Sku.VariableGuid] for ModuleFile in PlatformDataBase.Modules: @@ -625,33 +693,26 @@ class GenFds : continue else: ModuleList.append(Module) - GuidMatch = GuidPattern.match(ModuleFile.BaseName) - if GuidMatch is not None: - GuidXRefFile.write("%s %s\n" % (ModuleFile.BaseName, Module.BaseName)) + if GlobalData.gGuidPattern.match(ModuleFile.BaseName): + GuidXRefFile.append("%s %s\n" % (ModuleFile.BaseName, Module.BaseName)) else: - GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName)) - for key, item in Module.Protocols.items(): - GuidDict[key] = item - for key, item in Module.Guids.items(): - GuidDict[key] = item - for key, item in Module.Ppis.items(): - GuidDict[key] = item + GuidXRefFile.append("%s %s\n" % (Module.Guid, Module.BaseName)) + GuidDict.update(Module.Protocols) + GuidDict.update(Module.Guids) + GuidDict.update(Module.Ppis) for FvName in FdfParserObj.Profile.FvDict: for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList: - if not isinstance(FfsObj, FfsFileStatement.FileStatement): + if not isinstance(FfsObj, FileStatement): InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName))) FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] if FdfModule in ModuleList: continue else: ModuleList.append(FdfModule) - GuidXRefFile.write("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName)) - for key, item in FdfModule.Protocols.items(): - GuidDict[key] = item - for key, item in FdfModule.Guids.items(): - GuidDict[key] = item - for key, item in FdfModule.Ppis.items(): - GuidDict[key] = item + GuidXRefFile.append("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName)) + GuidDict.update(FdfModule.Protocols) + GuidDict.update(FdfModule.Guids) + GuidDict.update(FdfModule.Ppis) else: FileStatementGuid = FfsObj.NameGuid if FileStatementGuid in FileGuidList: @@ -660,13 +721,13 @@ class GenFds : FileGuidList.append(FileStatementGuid) Name = [] FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs') - FfsPath = glob.glob(os.path.join(FfsPath, FileStatementGuid) + '*') + FfsPath = glob(os.path.join(FfsPath, FileStatementGuid) + TAB_STAR) if not FfsPath: continue if not os.path.exists(FfsPath[0]): continue MatchDict = {} - ReFileEnds = re.compile('\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.te.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$') + ReFileEnds = compile('\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.te.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$') FileList = os.listdir(FfsPath[0]) for File in FileList: Match = ReFileEnds.search(File) @@ -709,30 +770,25 @@ class GenFds : continue Name = ' '.join(Name) if isinstance(Name, type([])) else Name - GuidXRefFile.write("%s %s\n" %(FileStatementGuid, Name)) + GuidXRefFile.append("%s %s\n" %(FileStatementGuid, Name)) # Append GUIDs, Protocols, and PPIs to the Xref file - GuidXRefFile.write("\n") + GuidXRefFile.append("\n") for key, item in GuidDict.items(): - GuidXRefFile.write("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key)) + GuidXRefFile.append("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key)) - if GuidXRefFile.getvalue(): - SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False) + if GuidXRefFile: + GuidXRefFile = ''.join(GuidXRefFile) + SaveFileOnChange(GuidXRefFileName, GuidXRefFile, False) GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName) elif os.path.exists(GuidXRefFileName): os.remove(GuidXRefFileName) - GuidXRefFile.close() - ##Define GenFd as static function - GenFd = staticmethod(GenFd) - GetFvBlockSize = staticmethod(GetFvBlockSize) - DisplayFvSpaceInfo = staticmethod(DisplayFvSpaceInfo) - PreprocessImage = staticmethod(PreprocessImage) - GenerateGuidXRefFile = staticmethod(GenerateGuidXRefFile) if __name__ == '__main__': r = main() ## 0-127 is a safe return range, and 1 is a standard default error - if r < 0 or r > 127: r = 1 - sys.exit(r) + if r < 0 or r > 127: + r = 1 + exit(r)