| ## @file | |
| # Global variables for GenFds | |
| # | |
| # Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR> | |
| # | |
| # SPDX-License-Identifier: BSD-2-Clause-Patent | |
| # | |
| ## | |
| # Import Modules | |
| # | |
| from __future__ import print_function | |
| from __future__ import absolute_import | |
| import Common.LongFilePathOs as os | |
| import sys | |
| from sys import stdout | |
| from subprocess import PIPE,Popen | |
| from struct import Struct | |
| from array import array | |
| from Common.BuildToolError import COMMAND_FAILURE,GENFDS_ERROR | |
| from Common import EdkLogger | |
| from Common.Misc import SaveFileOnChange | |
| from Common.TargetTxtClassObject import TargetTxtDict | |
| from Common.ToolDefClassObject import ToolDefDict,gDefaultToolsDefFile | |
| from AutoGen.BuildEngine import ToolBuildRule | |
| import Common.DataType as DataType | |
| from Common.Misc import PathClass,CreateDirectory | |
| from Common.LongFilePathSupport import OpenLongFilePath as open | |
| from Common.MultipleWorkspace import MultipleWorkspace as mws | |
| import Common.GlobalData as GlobalData | |
| from Common.BuildToolError import * | |
| from AutoGen.AutoGen import CalculatePriorityValue | |
| ## Global variables | |
| # | |
| # | |
| class GenFdsGlobalVariable: | |
| FvDir = '' | |
| OutputDirDict = {} | |
| BinDir = '' | |
| # will be FvDir + os.sep + 'Ffs' | |
| FfsDir = '' | |
| FdfParser = None | |
| WorkSpace = None | |
| WorkSpaceDir = '' | |
| ConfDir = '' | |
| OutputDirFromDscDict = {} | |
| TargetName = '' | |
| ToolChainTag = '' | |
| RuleDict = {} | |
| ArchList = None | |
| ActivePlatform = None | |
| FvAddressFileName = '' | |
| VerboseMode = False | |
| DebugLevel = -1 | |
| SharpCounter = 0 | |
| SharpNumberPerLine = 40 | |
| FdfFile = '' | |
| FdfFileTimeStamp = 0 | |
| FixedLoadAddress = False | |
| PlatformName = '' | |
| BuildRuleFamily = DataType.TAB_COMPILER_MSFT | |
| ToolChainFamily = DataType.TAB_COMPILER_MSFT | |
| __BuildRuleDatabase = None | |
| GuidToolDefinition = {} | |
| FfsCmdDict = {} | |
| SecCmdList = [] | |
| CopyList = [] | |
| ModuleFile = '' | |
| EnableGenfdsMultiThread = True | |
| # | |
| # The list whose element are flags to indicate if large FFS or SECTION files exist in FV. | |
| # At the beginning of each generation of FV, false flag is appended to the list, | |
| # after the call to GenerateSection returns, check the size of the output file, | |
| # if it is greater than 0xFFFFFF, the tail flag in list is set to true, | |
| # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv. | |
| # At the end of generation of FV, pop the flag. | |
| # List is used as a stack to handle nested FV generation. | |
| # | |
| LargeFileInFvFlags = [] | |
| EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A' | |
| LARGE_FILE_SIZE = 0x1000000 | |
| SectionHeader = Struct("3B 1B") | |
| # FvName, FdName, CapName in FDF, Image file name | |
| ImageBinDict = {} | |
| ## LoadBuildRule | |
| # | |
| @staticmethod | |
| def _LoadBuildRule(): | |
| if GenFdsGlobalVariable.__BuildRuleDatabase: | |
| return GenFdsGlobalVariable.__BuildRuleDatabase | |
| BuildRule = ToolBuildRule() | |
| GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule.ToolBuildRule | |
| TargetObj = TargetTxtDict() | |
| ToolDefinitionFile = TargetObj.Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF] | |
| if ToolDefinitionFile == '': | |
| ToolDefinitionFile = os.path.join('Conf', gDefaultToolsDefFile) | |
| if os.path.isfile(ToolDefinitionFile): | |
| ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf"))) | |
| ToolDefinition = ToolDefObj.ToolDef.ToolsDefTxtDatabase | |
| if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \ | |
| and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \ | |
| and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]: | |
| GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag] | |
| if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \ | |
| and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \ | |
| and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]: | |
| GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag] | |
| return GenFdsGlobalVariable.__BuildRuleDatabase | |
| ## GetBuildRules | |
| # @param Inf: object of InfBuildData | |
| # @param Arch: current arch | |
| # | |
| @staticmethod | |
| def GetBuildRules(Inf, Arch): | |
| if not Arch: | |
| Arch = DataType.TAB_COMMON | |
| if not Arch in GenFdsGlobalVariable.OutputDirDict: | |
| return {} | |
| BuildRuleDatabase = GenFdsGlobalVariable._LoadBuildRule() | |
| if not BuildRuleDatabase: | |
| return {} | |
| PathClassObj = PathClass(Inf.MetaFile.File, | |
| GenFdsGlobalVariable.WorkSpaceDir) | |
| BuildDir = os.path.join( | |
| GenFdsGlobalVariable.OutputDirDict[Arch], | |
| Arch, | |
| PathClassObj.SubDir, | |
| PathClassObj.BaseName | |
| ) | |
| BinDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch) | |
| Macro = { | |
| "WORKSPACE":GenFdsGlobalVariable.WorkSpaceDir, | |
| "MODULE_NAME":Inf.BaseName, | |
| "MODULE_GUID":Inf.Guid, | |
| "MODULE_VERSION":Inf.Version, | |
| "MODULE_TYPE":Inf.ModuleType, | |
| "MODULE_FILE":str(PathClassObj), | |
| "MODULE_FILE_BASE_NAME":PathClassObj.BaseName, | |
| "MODULE_RELATIVE_DIR":PathClassObj.SubDir, | |
| "MODULE_DIR":PathClassObj.SubDir, | |
| "BASE_NAME":Inf.BaseName, | |
| "ARCH":Arch, | |
| "TOOLCHAIN":GenFdsGlobalVariable.ToolChainTag, | |
| "TOOLCHAIN_TAG":GenFdsGlobalVariable.ToolChainTag, | |
| "TOOL_CHAIN_TAG":GenFdsGlobalVariable.ToolChainTag, | |
| "TARGET":GenFdsGlobalVariable.TargetName, | |
| "BUILD_DIR":GenFdsGlobalVariable.OutputDirDict[Arch], | |
| "BIN_DIR":BinDir, | |
| "LIB_DIR":BinDir, | |
| "MODULE_BUILD_DIR":BuildDir, | |
| "OUTPUT_DIR":os.path.join(BuildDir, "OUTPUT"), | |
| "DEBUG_DIR":os.path.join(BuildDir, "DEBUG") | |
| } | |
| BuildRules = {} | |
| for Type in BuildRuleDatabase.FileTypeList: | |
| #first try getting build rule by BuildRuleFamily | |
| RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily] | |
| if not RuleObject: | |
| # build type is always module type, but ... | |
| if Inf.ModuleType != Inf.BuildType: | |
| RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily] | |
| #second try getting build rule by ToolChainFamily | |
| if not RuleObject: | |
| RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily] | |
| if not RuleObject: | |
| # build type is always module type, but ... | |
| if Inf.ModuleType != Inf.BuildType: | |
| RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily] | |
| if not RuleObject: | |
| continue | |
| RuleObject = RuleObject.Instantiate(Macro) | |
| BuildRules[Type] = RuleObject | |
| for Ext in RuleObject.SourceFileExtList: | |
| BuildRules[Ext] = RuleObject | |
| return BuildRules | |
| ## GetModuleCodaTargetList | |
| # | |
| # @param Inf: object of InfBuildData | |
| # @param Arch: current arch | |
| # | |
| @staticmethod | |
| def GetModuleCodaTargetList(Inf, Arch): | |
| BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch) | |
| if not BuildRules: | |
| return [] | |
| TargetList = set() | |
| FileList = [] | |
| if not Inf.IsBinaryModule: | |
| for File in Inf.Sources: | |
| if File.TagName in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainTag} and \ | |
| File.ToolChainFamily in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainFamily}: | |
| FileList.append((File, DataType.TAB_UNKNOWN_FILE)) | |
| for File in Inf.Binaries: | |
| if File.Target in {DataType.TAB_COMMON, DataType.TAB_STAR, GenFdsGlobalVariable.TargetName}: | |
| FileList.append((File, File.Type)) | |
| for File, FileType in FileList: | |
| LastTarget = None | |
| RuleChain = [] | |
| SourceList = [File] | |
| Index = 0 | |
| while Index < len(SourceList): | |
| Source = SourceList[Index] | |
| Index = Index + 1 | |
| if File.IsBinary and File == Source and Inf.Binaries and File in Inf.Binaries: | |
| # Skip all files that are not binary libraries | |
| if not Inf.LibraryClass: | |
| continue | |
| RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE] | |
| elif FileType in BuildRules: | |
| RuleObject = BuildRules[FileType] | |
| elif Source.Ext in BuildRules: | |
| RuleObject = BuildRules[Source.Ext] | |
| else: | |
| # stop at no more rules | |
| if LastTarget: | |
| TargetList.add(str(LastTarget)) | |
| break | |
| FileType = RuleObject.SourceFileType | |
| # stop at STATIC_LIBRARY for library | |
| if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY: | |
| if LastTarget: | |
| TargetList.add(str(LastTarget)) | |
| break | |
| Target = RuleObject.Apply(Source) | |
| if not Target: | |
| if LastTarget: | |
| TargetList.add(str(LastTarget)) | |
| break | |
| elif not Target.Outputs: | |
| # Only do build for target with outputs | |
| TargetList.add(str(Target)) | |
| # to avoid cyclic rule | |
| if FileType in RuleChain: | |
| break | |
| RuleChain.append(FileType) | |
| SourceList.extend(Target.Outputs) | |
| LastTarget = Target | |
| FileType = DataType.TAB_UNKNOWN_FILE | |
| for Cmd in Target.Commands: | |
| if "$(CP)" == Cmd.split()[0]: | |
| CpTarget = Cmd.split()[2] | |
| TargetList.add(CpTarget) | |
| return list(TargetList) | |
| ## SetDir() | |
| # | |
| # @param OutputDir Output directory | |
| # @param FdfParser FDF contents parser | |
| # @param Workspace The directory of workspace | |
| # @param ArchList The Arch list of platform | |
| # | |
| @staticmethod | |
| def SetDir (OutputDir, FdfParser, WorkSpace, ArchList): | |
| GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir:%s" % OutputDir) | |
| GenFdsGlobalVariable.FdfParser = FdfParser | |
| GenFdsGlobalVariable.WorkSpace = WorkSpace | |
| GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY) | |
| if not os.path.exists(GenFdsGlobalVariable.FvDir): | |
| os.makedirs(GenFdsGlobalVariable.FvDir) | |
| GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs') | |
| if not os.path.exists(GenFdsGlobalVariable.FfsDir): | |
| os.makedirs(GenFdsGlobalVariable.FfsDir) | |
| # | |
| # Create FV Address inf file | |
| # | |
| GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf') | |
| FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w') | |
| # | |
| # Add [Options] | |
| # | |
| FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK) | |
| BsAddress = '0' | |
| for Arch in ArchList: | |
| if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress: | |
| BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress | |
| break | |
| FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \ | |
| BsAddress + \ | |
| DataType.TAB_LINE_BREAK) | |
| RtAddress = '0' | |
| for Arch in reversed(ArchList): | |
| temp = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress | |
| if temp: | |
| RtAddress = temp | |
| break | |
| FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \ | |
| RtAddress + \ | |
| DataType.TAB_LINE_BREAK) | |
| FvAddressFile.close() | |
| @staticmethod | |
| def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData): | |
| GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile | |
| GenFdsGlobalVariable.FdfParser = FdfParser | |
| GenFdsGlobalVariable.WorkSpace = WorkSpace.Db | |
| GenFdsGlobalVariable.ArchList = ArchList | |
| GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"] | |
| GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"] | |
| GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform | |
| GenFdsGlobalVariable.ConfDir = GlobalData.gConfDirectory | |
| GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread | |
| for Arch in ArchList: | |
| GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath( | |
| os.path.join(GlobalData.gWorkspace, | |
| WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'], | |
| GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory, | |
| GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN'])) | |
| GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath( | |
| WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, | |
| GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory) | |
| GenFdsGlobalVariable.PlatformName = WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, | |
| GlobalData.gGlobalDefines['TARGET'], | |
| GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName | |
| GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY) | |
| if not os.path.exists(GenFdsGlobalVariable.FvDir): | |
| os.makedirs(GenFdsGlobalVariable.FvDir) | |
| GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs') | |
| if not os.path.exists(GenFdsGlobalVariable.FfsDir): | |
| os.makedirs(GenFdsGlobalVariable.FfsDir) | |
| # | |
| # Create FV Address inf file | |
| # | |
| GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf') | |
| FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w') | |
| # | |
| # Add [Options] | |
| # | |
| FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK) | |
| BsAddress = '0' | |
| for Arch in ArchList: | |
| BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, | |
| GlobalData.gGlobalDefines['TARGET'], | |
| GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress | |
| if BsAddress: | |
| break | |
| FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \ | |
| BsAddress + \ | |
| DataType.TAB_LINE_BREAK) | |
| RtAddress = '0' | |
| for Arch in reversed(ArchList): | |
| temp = GenFdsGlobalVariable.WorkSpace.BuildObject[ | |
| GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'], | |
| GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress | |
| if temp: | |
| RtAddress = temp | |
| break | |
| FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \ | |
| RtAddress + \ | |
| DataType.TAB_LINE_BREAK) | |
| FvAddressFile.close() | |
| ## ReplaceWorkspaceMacro() | |
| # | |
| # @param String String that may contain macro | |
| # | |
| @staticmethod | |
| def ReplaceWorkspaceMacro(String): | |
| String = mws.handleWsMacro(String) | |
| Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir) | |
| if os.path.exists(Str): | |
| if not os.path.isabs(Str): | |
| Str = os.path.abspath(Str) | |
| else: | |
| Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String) | |
| return os.path.normpath(Str) | |
| ## Check if the input files are newer than output files | |
| # | |
| # @param Output Path of output file | |
| # @param Input Path list of input files | |
| # | |
| # @retval True if Output doesn't exist, or any Input is newer | |
| # @retval False if all Input is older than Output | |
| # | |
| @staticmethod | |
| def NeedsUpdate(Output, Input): | |
| if not os.path.exists(Output): | |
| return True | |
| # always update "Output" if no "Input" given | |
| if not Input: | |
| return True | |
| # if fdf file is changed after the 'Output" is generated, update the 'Output' | |
| OutputTime = os.path.getmtime(Output) | |
| if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime: | |
| return True | |
| for F in Input: | |
| # always update "Output" if any "Input" doesn't exist | |
| if not os.path.exists(F): | |
| return True | |
| # always update "Output" if any "Input" is newer than "Output" | |
| if os.path.getmtime(F) > OutputTime: | |
| return True | |
| return False | |
| @staticmethod | |
| def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None, | |
| GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=[], BuildNumber=None, DummyFile=None, IsMakefile=False): | |
| Cmd = ["GenSec"] | |
| if Type: | |
| Cmd += ("-s", Type) | |
| if CompressionType: | |
| Cmd += ("-c", CompressionType) | |
| if Guid: | |
| Cmd += ("-g", Guid) | |
| if DummyFile: | |
| Cmd += ("--dummy", DummyFile) | |
| if GuidHdrLen: | |
| Cmd += ("-l", GuidHdrLen) | |
| #Add each guided attribute | |
| for Attr in GuidAttr: | |
| Cmd += ("-r", Attr) | |
| #Section Align is only for dummy section without section type | |
| for SecAlign in InputAlign: | |
| Cmd += ("--sectionalign", SecAlign) | |
| CommandFile = Output + '.txt' | |
| if Ui: | |
| if IsMakefile: | |
| if Ui == "$(MODULE_NAME)": | |
| Cmd += ('-n', Ui) | |
| else: | |
| Cmd += ("-n", '"' + Ui + '"') | |
| Cmd += ("-o", Output) | |
| if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: | |
| GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip()) | |
| else: | |
| SectionData = array('B', [0, 0, 0, 0]) | |
| SectionData.fromlist(array('B',Ui.encode('utf-16-le')).tolist()) | |
| SectionData.append(0) | |
| SectionData.append(0) | |
| Len = len(SectionData) | |
| GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15) | |
| DirName = os.path.dirname(Output) | |
| if not CreateDirectory(DirName): | |
| EdkLogger.error(None, FILE_CREATE_FAILURE, "Could not create directory %s" % DirName) | |
| else: | |
| if DirName == '': | |
| DirName = os.getcwd() | |
| if not os.access(DirName, os.W_OK): | |
| EdkLogger.error(None, PERMISSION_FAILURE, "Do not have write permission on directory %s" % DirName) | |
| try: | |
| with open(Output, "wb") as Fd: | |
| SectionData.tofile(Fd) | |
| Fd.flush() | |
| except IOError as X: | |
| EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s' % X) | |
| elif Ver: | |
| Cmd += ("-n", Ver) | |
| if BuildNumber: | |
| Cmd += ("-j", BuildNumber) | |
| Cmd += ("-o", Output) | |
| SaveFileOnChange(CommandFile, ' '.join(Cmd), False) | |
| if IsMakefile: | |
| if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: | |
| GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip()) | |
| else: | |
| if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): | |
| return | |
| GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section") | |
| else: | |
| Cmd += ("-o", Output) | |
| Cmd += Input | |
| SaveFileOnChange(CommandFile, ' '.join(Cmd), False) | |
| if IsMakefile: | |
| if sys.platform == "win32": | |
| Cmd = ['if', 'exist', Input[0]] + Cmd | |
| else: | |
| Cmd = ['-test', '-e', Input[0], "&&"] + Cmd | |
| if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: | |
| GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip()) | |
| elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): | |
| GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) | |
| GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section") | |
| if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and | |
| GenFdsGlobalVariable.LargeFileInFvFlags): | |
| GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True | |
| @staticmethod | |
| def GetAlignment (AlignString): | |
| if not AlignString: | |
| return 0 | |
| if AlignString.endswith('K'): | |
| return int (AlignString.rstrip('K')) * 1024 | |
| if AlignString.endswith('M'): | |
| return int (AlignString.rstrip('M')) * 1024 * 1024 | |
| if AlignString.endswith('G'): | |
| return int (AlignString.rstrip('G')) * 1024 * 1024 * 1024 | |
| return int (AlignString) | |
| @staticmethod | |
| def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None, | |
| SectionAlign=None, MakefilePath=None): | |
| Cmd = ["GenFfs", "-t", Type, "-g", Guid] | |
| mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"] | |
| if Fixed == True: | |
| Cmd.append("-x") | |
| if CheckSum: | |
| Cmd.append("-s") | |
| if Align: | |
| if Align not in mFfsValidAlign: | |
| Align = GenFdsGlobalVariable.GetAlignment (Align) | |
| for index in range(0, len(mFfsValidAlign) - 1): | |
| if ((Align > GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index])) and (Align <= GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index + 1]))): | |
| break | |
| Align = mFfsValidAlign[index + 1] | |
| Cmd += ("-a", Align) | |
| Cmd += ("-o", Output) | |
| for I in range(0, len(Input)): | |
| if MakefilePath: | |
| Cmd += ("-oi", Input[I]) | |
| else: | |
| Cmd += ("-i", Input[I]) | |
| if SectionAlign and SectionAlign[I]: | |
| Cmd += ("-n", SectionAlign[I]) | |
| CommandFile = Output + '.txt' | |
| SaveFileOnChange(CommandFile, ' '.join(Cmd), False) | |
| GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) | |
| if MakefilePath: | |
| if (tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict: | |
| GenFdsGlobalVariable.FfsCmdDict[tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)] = MakefilePath | |
| GenFdsGlobalVariable.SecCmdList = [] | |
| GenFdsGlobalVariable.CopyList = [] | |
| else: | |
| if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): | |
| return | |
| GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS") | |
| @staticmethod | |
| def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False, | |
| AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None): | |
| if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList): | |
| return | |
| GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) | |
| Cmd = ["GenFv"] | |
| if BaseAddress: | |
| Cmd += ("-r", BaseAddress) | |
| if ForceRebase == False: | |
| Cmd += ("-F", "FALSE") | |
| elif ForceRebase == True: | |
| Cmd += ("-F", "TRUE") | |
| if Capsule: | |
| Cmd.append("-c") | |
| if Dump: | |
| Cmd.append("-p") | |
| if AddressFile: | |
| Cmd += ("-a", AddressFile) | |
| if MapFile: | |
| Cmd += ("-m", MapFile) | |
| if FileSystemGuid: | |
| Cmd += ("-g", FileSystemGuid) | |
| Cmd += ("-o", Output) | |
| for I in Input: | |
| Cmd += ("-i", I) | |
| GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV") | |
| @staticmethod | |
| def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False, | |
| Strip=False, Replace=False, TimeStamp=None, Join=False, | |
| Align=None, Padding=None, Convert=False, IsMakefile=False): | |
| if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile: | |
| return | |
| GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) | |
| Cmd = ["GenFw"] | |
| if Type.lower() == "te": | |
| Cmd.append("-t") | |
| if SubType: | |
| Cmd += ("-e", SubType) | |
| if TimeStamp: | |
| Cmd += ("-s", TimeStamp) | |
| if Align: | |
| Cmd += ("-a", Align) | |
| if Padding: | |
| Cmd += ("-p", Padding) | |
| if Zero: | |
| Cmd.append("-z") | |
| if Strip: | |
| Cmd.append("-l") | |
| if Replace: | |
| Cmd.append("-r") | |
| if Join: | |
| Cmd.append("-j") | |
| if Convert: | |
| Cmd.append("-m") | |
| Cmd += ("-o", Output) | |
| Cmd += Input | |
| if IsMakefile: | |
| if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: | |
| GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip()) | |
| else: | |
| GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image") | |
| @staticmethod | |
| def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None, | |
| Revision=None, DeviceId=None, VendorId=None, IsMakefile=False): | |
| InputList = [] | |
| Cmd = ["EfiRom"] | |
| if EfiInput: | |
| if Compress: | |
| Cmd.append("-ec") | |
| else: | |
| Cmd.append("-e") | |
| for EfiFile in EfiInput: | |
| Cmd.append(EfiFile) | |
| InputList.append (EfiFile) | |
| if BinaryInput: | |
| Cmd.append("-b") | |
| for BinFile in BinaryInput: | |
| Cmd.append(BinFile) | |
| InputList.append (BinFile) | |
| # Check List | |
| if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList) and not IsMakefile: | |
| return | |
| GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList)) | |
| if ClassCode: | |
| Cmd += ("-l", ClassCode) | |
| if Revision: | |
| Cmd += ("-r", Revision) | |
| if DeviceId: | |
| Cmd += ("-i", DeviceId) | |
| if VendorId: | |
| Cmd += ("-f", VendorId) | |
| Cmd += ("-o", Output) | |
| if IsMakefile: | |
| if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: | |
| GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip()) | |
| else: | |
| GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom") | |
| @staticmethod | |
| def GuidTool(Output, Input, ToolPath, Options='', returnValue=[], IsMakefile=False): | |
| if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile: | |
| return | |
| GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) | |
| Cmd = [ToolPath, ] | |
| Cmd += Options.split(' ') | |
| Cmd += ("-o", Output) | |
| Cmd += Input | |
| if IsMakefile: | |
| if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: | |
| GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip()) | |
| else: | |
| GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue) | |
| @staticmethod | |
| def CallExternalTool (cmd, errorMess, returnValue=[]): | |
| if type(cmd) not in (tuple, list): | |
| GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool") | |
| if GenFdsGlobalVariable.DebugLevel != -1: | |
| cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel)) | |
| GenFdsGlobalVariable.InfLogger (cmd) | |
| if GenFdsGlobalVariable.VerboseMode: | |
| cmd += ('-v',) | |
| GenFdsGlobalVariable.InfLogger (cmd) | |
| else: | |
| stdout.write ('#') | |
| stdout.flush() | |
| GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1 | |
| if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0: | |
| stdout.write('\n') | |
| try: | |
| PopenObject = Popen(' '.join(cmd), stdout=PIPE, stderr=PIPE, shell=True) | |
| except Exception as X: | |
| EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0])) | |
| (out, error) = PopenObject.communicate() | |
| while PopenObject.returncode is None: | |
| PopenObject.wait() | |
| if returnValue != [] and returnValue[0] != 0: | |
| #get command return value | |
| returnValue[0] = PopenObject.returncode | |
| return | |
| if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1: | |
| GenFdsGlobalVariable.InfLogger ("Return Value = %d" % PopenObject.returncode) | |
| GenFdsGlobalVariable.InfLogger(out.decode(encoding='utf-8', errors='ignore')) | |
| GenFdsGlobalVariable.InfLogger(error.decode(encoding='utf-8', errors='ignore')) | |
| if PopenObject.returncode != 0: | |
| print("###", cmd) | |
| EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess) | |
| @staticmethod | |
| def VerboseLogger (msg): | |
| EdkLogger.verbose(msg) | |
| @staticmethod | |
| def InfLogger (msg): | |
| EdkLogger.info(msg) | |
| @staticmethod | |
| def ErrorLogger (msg, File=None, Line=None, ExtraData=None): | |
| EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData) | |
| @staticmethod | |
| def DebugLogger (Level, msg): | |
| EdkLogger.debug(Level, msg) | |
| ## MacroExtend() | |
| # | |
| # @param Str String that may contain macro | |
| # @param MacroDict Dictionary that contains macro value pair | |
| # | |
| @staticmethod | |
| def MacroExtend (Str, MacroDict=None, Arch=DataType.TAB_COMMON): | |
| if Str is None: | |
| return None | |
| Dict = {'$(WORKSPACE)': GenFdsGlobalVariable.WorkSpaceDir, | |
| # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc, | |
| '$(TARGET)': GenFdsGlobalVariable.TargetName, | |
| '$(TOOL_CHAIN_TAG)': GenFdsGlobalVariable.ToolChainTag, | |
| '$(SPACE)': ' ' | |
| } | |
| if Arch != DataType.TAB_COMMON and Arch in GenFdsGlobalVariable.ArchList: | |
| OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch] | |
| else: | |
| OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]] | |
| Dict['$(OUTPUT_DIRECTORY)'] = OutputDir | |
| if MacroDict: | |
| Dict.update(MacroDict) | |
| for key in Dict: | |
| if Str.find(key) >= 0: | |
| Str = Str.replace (key, Dict[key]) | |
| if Str.find('$(ARCH)') >= 0: | |
| if len(GenFdsGlobalVariable.ArchList) == 1: | |
| Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0]) | |
| else: | |
| EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str) | |
| return Str | |
| ## GetPcdValue() | |
| # | |
| # @param PcdPattern pattern that labels a PCD. | |
| # | |
| @staticmethod | |
| def GetPcdValue (PcdPattern): | |
| if PcdPattern is None: | |
| return None | |
| if PcdPattern.startswith('PCD('): | |
| PcdPair = PcdPattern[4:].rstrip(')').strip().split('.') | |
| else: | |
| PcdPair = PcdPattern.strip().split('.') | |
| TokenSpace = PcdPair[0] | |
| TokenCName = PcdPair[1] | |
| for Arch in GenFdsGlobalVariable.ArchList: | |
| Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] | |
| PcdDict = Platform.Pcds | |
| for Key in PcdDict: | |
| PcdObj = PcdDict[Key] | |
| if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace): | |
| if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD: | |
| EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern) | |
| if PcdObj.DatumType != DataType.TAB_VOID: | |
| EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern) | |
| return PcdObj.DefaultValue | |
| for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, | |
| Arch, | |
| GenFdsGlobalVariable.TargetName, | |
| GenFdsGlobalVariable.ToolChainTag): | |
| PcdDict = Package.Pcds | |
| for Key in PcdDict: | |
| PcdObj = PcdDict[Key] | |
| if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace): | |
| if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD: | |
| EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern) | |
| if PcdObj.DatumType != DataType.TAB_VOID: | |
| EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern) | |
| return PcdObj.DefaultValue | |
| return '' | |
| ## FindExtendTool() | |
| # | |
| # Find location of tools to process data | |
| # | |
| # @param KeyStringList Filter for inputs of section generation | |
| # @param CurrentArchList Arch list | |
| # @param NameGuid The Guid name | |
| # | |
| def FindExtendTool(KeyStringList, CurrentArchList, NameGuid): | |
| if GenFdsGlobalVariable.GuidToolDefinition: | |
| if NameGuid in GenFdsGlobalVariable.GuidToolDefinition: | |
| return GenFdsGlobalVariable.GuidToolDefinition[NameGuid] | |
| ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf"))) | |
| ToolDef = ToolDefObj.ToolDef | |
| ToolDb = ToolDef.ToolsDefTxtDatabase | |
| # if user not specify filter, try to deduce it from global data. | |
| if KeyStringList is None or KeyStringList == []: | |
| Target = GenFdsGlobalVariable.TargetName | |
| ToolChain = GenFdsGlobalVariable.ToolChainTag | |
| if ToolChain not in ToolDb['TOOL_CHAIN_TAG']: | |
| EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain) | |
| KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]] | |
| for Arch in CurrentArchList: | |
| if Target + '_' + ToolChain + '_' + Arch not in KeyStringList: | |
| KeyStringList.append(Target + '_' + ToolChain + '_' + Arch) | |
| ToolPathTmp = None | |
| ToolOption = None | |
| for Arch in CurrentArchList: | |
| MatchItem = None | |
| MatchPathItem = None | |
| MatchOptionsItem = None | |
| for KeyString in KeyStringList: | |
| KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_') | |
| if KeyStringArch != Arch: | |
| continue | |
| for Item in ToolDef.ToolsDefTxtDictionary: | |
| if len(Item.split('_')) < 5: | |
| continue | |
| ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_') | |
| if ItemTarget == DataType.TAB_STAR: | |
| ItemTarget = KeyStringBuildTarget | |
| if ItemToolChain == DataType.TAB_STAR: | |
| ItemToolChain = KeyStringToolChain | |
| if ItemArch == DataType.TAB_STAR: | |
| ItemArch = KeyStringArch | |
| if ItemTarget != KeyStringBuildTarget: | |
| continue | |
| if ItemToolChain != KeyStringToolChain: | |
| continue | |
| if ItemArch != KeyStringArch: | |
| continue | |
| if ItemAttr != DataType.TAB_GUID: | |
| # Not GUID attribute | |
| continue | |
| if ToolDef.ToolsDefTxtDictionary[Item].lower() != NameGuid.lower(): | |
| # No GUID value match | |
| continue | |
| if MatchItem: | |
| if MatchItem.split('_')[3] == ItemTool: | |
| # Tool name is the same | |
| continue | |
| if CalculatePriorityValue(MatchItem) > CalculatePriorityValue(Item): | |
| # Current MatchItem is higher priority than new match item | |
| continue | |
| MatchItem = Item | |
| if not MatchItem: | |
| continue | |
| ToolName = MatchItem.split('_')[3] | |
| for Item in ToolDef.ToolsDefTxtDictionary: | |
| if len(Item.split('_')) < 5: | |
| continue | |
| ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_') | |
| if ItemTarget == DataType.TAB_STAR: | |
| ItemTarget = KeyStringBuildTarget | |
| if ItemToolChain == DataType.TAB_STAR: | |
| ItemToolChain = KeyStringToolChain | |
| if ItemArch == DataType.TAB_STAR: | |
| ItemArch = KeyStringArch | |
| if ItemTarget != KeyStringBuildTarget: | |
| continue | |
| if ItemToolChain != KeyStringToolChain: | |
| continue | |
| if ItemArch != KeyStringArch: | |
| continue | |
| if ItemTool != ToolName: | |
| continue | |
| if ItemAttr == 'PATH': | |
| if MatchPathItem: | |
| if CalculatePriorityValue(MatchPathItem) <= CalculatePriorityValue(Item): | |
| MatchPathItem = Item | |
| else: | |
| MatchPathItem = Item | |
| if ItemAttr == 'FLAGS': | |
| if MatchOptionsItem: | |
| if CalculatePriorityValue(MatchOptionsItem) <= CalculatePriorityValue(Item): | |
| MatchOptionsItem = Item | |
| else: | |
| MatchOptionsItem = Item | |
| if MatchPathItem: | |
| ToolPathTmp = ToolDef.ToolsDefTxtDictionary[MatchPathItem] | |
| if MatchOptionsItem: | |
| ToolOption = ToolDef.ToolsDefTxtDictionary[MatchOptionsItem] | |
| for Arch in CurrentArchList: | |
| MatchItem = None | |
| MatchPathItem = None | |
| MatchOptionsItem = None | |
| for KeyString in KeyStringList: | |
| KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_') | |
| if KeyStringArch != Arch: | |
| continue | |
| Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, KeyStringBuildTarget, KeyStringToolChain] | |
| for Item in Platform.BuildOptions: | |
| if len(Item[1].split('_')) < 5: | |
| continue | |
| ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_') | |
| if ItemTarget == DataType.TAB_STAR: | |
| ItemTarget = KeyStringBuildTarget | |
| if ItemToolChain == DataType.TAB_STAR: | |
| ItemToolChain = KeyStringToolChain | |
| if ItemArch == DataType.TAB_STAR: | |
| ItemArch = KeyStringArch | |
| if ItemTarget != KeyStringBuildTarget: | |
| continue | |
| if ItemToolChain != KeyStringToolChain: | |
| continue | |
| if ItemArch != KeyStringArch: | |
| continue | |
| if ItemAttr != DataType.TAB_GUID: | |
| # Not GUID attribute match | |
| continue | |
| if Platform.BuildOptions[Item].lower() != NameGuid.lower(): | |
| # No GUID value match | |
| continue | |
| if MatchItem: | |
| if MatchItem[1].split('_')[3] == ItemTool: | |
| # Tool name is the same | |
| continue | |
| if CalculatePriorityValue(MatchItem[1]) > CalculatePriorityValue(Item[1]): | |
| # Current MatchItem is higher priority than new match item | |
| continue | |
| MatchItem = Item | |
| if not MatchItem: | |
| continue | |
| ToolName = MatchItem[1].split('_')[3] | |
| for Item in Platform.BuildOptions: | |
| if len(Item[1].split('_')) < 5: | |
| continue | |
| ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_') | |
| if ItemTarget == DataType.TAB_STAR: | |
| ItemTarget = KeyStringBuildTarget | |
| if ItemToolChain == DataType.TAB_STAR: | |
| ItemToolChain = KeyStringToolChain | |
| if ItemArch == DataType.TAB_STAR: | |
| ItemArch = KeyStringArch | |
| if ItemTarget != KeyStringBuildTarget: | |
| continue | |
| if ItemToolChain != KeyStringToolChain: | |
| continue | |
| if ItemArch != KeyStringArch: | |
| continue | |
| if ItemTool != ToolName: | |
| continue | |
| if ItemAttr == 'PATH': | |
| if MatchPathItem: | |
| if CalculatePriorityValue(MatchPathItem[1]) <= CalculatePriorityValue(Item[1]): | |
| MatchPathItem = Item | |
| else: | |
| MatchPathItem = Item | |
| if ItemAttr == 'FLAGS': | |
| if MatchOptionsItem: | |
| if CalculatePriorityValue(MatchOptionsItem[1]) <= CalculatePriorityValue(Item[1]): | |
| MatchOptionsItem = Item | |
| else: | |
| MatchOptionsItem = Item | |
| if MatchPathItem: | |
| ToolPathTmp = Platform.BuildOptions[MatchPathItem] | |
| if MatchOptionsItem: | |
| ToolOption = Platform.BuildOptions[MatchOptionsItem] | |
| GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption) | |
| return ToolPathTmp, ToolOption |