From ef3840c1ff320698523dd6b94ba7c86354392784 Mon Sep 17 00:00:00 2001 From: Michael D Kinney Date: Fri, 7 May 2021 08:40:29 -0700 Subject: [PATCH] BaseTools: Fix DSC override of Guided tool REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3359 If the DSC file provides an override of a Guided tool path and/or Guided tool GUID value, then make sure the one from the DSC file is used if it is higher priority than the Guided tool in the tools_def.txt file. This makes the Guided tool used by GenFds match the tool listed GuidedSectionTools.txt. Cc: Bob Feng Cc: Liming Gao Cc: Yuwei Chen Signed-off-by: Michael D Kinney Reviewed-by: Bob Feng --- .../Source/Python/AutoGen/PlatformAutoGen.py | 7 +- .../Python/GenFds/GenFdsGlobalVariable.py | 228 ++++++++++++------ BaseTools/Source/Python/build/build.py | 52 ++-- 3 files changed, 190 insertions(+), 97 deletions(-) diff --git a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py index 832c0da86b..592d4824a4 100644 --- a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py +++ b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py @@ -918,14 +918,13 @@ class PlatformAutoGen(AutoGen): if Tool in self._BuildOptionWithToolDef(RetVal) and Attr in self._BuildOptionWithToolDef(RetVal)[Tool]: # check if override is indicated if self._BuildOptionWithToolDef(RetVal)[Tool][Attr].startswith('='): - Value = self._BuildOptionWithToolDef(RetVal)[Tool][Attr][1:] + Value = self._BuildOptionWithToolDef(RetVal)[Tool][Attr][1:].strip() else: - if Attr != 'PATH': + # Do not append PATH or GUID + if Attr != 'PATH' and Attr != 'GUID': Value += " " + self._BuildOptionWithToolDef(RetVal)[Tool][Attr] else: Value = self._BuildOptionWithToolDef(RetVal)[Tool][Attr] - Def = '_'.join([self.BuildTarget, self.ToolChain, self.Arch, Tool, Attr]) - self.Workspace.ToolDef.ToolsDefTxtDictionary[Def] = Value if Attr == "PATH": # Don't put MAKE definition in the file if Tool != "MAKE": diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py index c31fc24870..25f9d54874 100644 --- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py +++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py @@ -32,6 +32,7 @@ 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 # @@ -850,6 +851,10 @@ class GenFdsGlobalVariable: # @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 @@ -864,86 +869,159 @@ def FindExtendTool(KeyStringList, CurrentArchList, NameGuid): if Target + '_' + ToolChain + '_' + Arch not in KeyStringList: KeyStringList.append(Target + '_' + ToolChain + '_' + Arch) - if GenFdsGlobalVariable.GuidToolDefinition: - if NameGuid in GenFdsGlobalVariable.GuidToolDefinition: - return GenFdsGlobalVariable.GuidToolDefinition[NameGuid] - - ToolDefinition = ToolDef.ToolsDefTxtDictionary ToolPathTmp = None ToolOption = None - ToolPathKey = None - ToolOptionKey = None - KeyList = None - for tool_def in ToolDefinition.items(): - KeyList = tool_def[0].split('_') - if len(KeyList) < 5: - continue - if KeyList[4] != DataType.TAB_GUID: - continue - if NameGuid.lower() != tool_def[1].lower(): - continue - Key = KeyList[0] + \ - '_' + \ - KeyList[1] + \ - '_' + \ - KeyList[2] + for Arch in CurrentArchList: + MatchItem = None + MatchPathItem = None + MatchOptionsItem = None for KeyString in KeyStringList: KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_') - if KeyList[0] == DataType.TAB_STAR: - KeyList[0] = KeyStringBuildTarget - if KeyList[1] == DataType.TAB_STAR: - KeyList[1] = KeyStringToolChain - if KeyList[2] == DataType.TAB_STAR: - KeyList[2] = KeyStringArch - if KeyList[0] == KeyStringBuildTarget and KeyList[1] == KeyStringToolChain and KeyList[2] == KeyStringArch: - ToolPathKey = Key + '_' + KeyList[3] + '_PATH' - ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS' - ToolPath = ToolDefinition.get(ToolPathKey) - ToolOption = ToolDefinition.get(ToolOptionKey) - if ToolPathTmp is None: - ToolPathTmp = ToolPath - else: - if ToolPathTmp != ToolPath: - EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath)) + 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] - BuildOption = {} for Arch in CurrentArchList: - Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] - # key is (ToolChainFamily, ToolChain, CodeBase) - for item in Platform.BuildOptions: - if '_PATH' in item[1] or '_FLAGS' in item[1] or '_GUID' in item[1]: - if not item[0] or (item[0] and GenFdsGlobalVariable.ToolChainFamily== item[0]): - if item[1] not in BuildOption: - BuildOption[item[1]] = Platform.BuildOptions[item] - if BuildOption: - ToolList = [DataType.TAB_TOD_DEFINES_TARGET, DataType.TAB_TOD_DEFINES_TOOL_CHAIN_TAG, DataType.TAB_TOD_DEFINES_TARGET_ARCH] - for Index in range(2, -1, -1): - for Key in list(BuildOption.keys()): - List = Key.split('_') - if List[Index] == DataType.TAB_STAR: - for String in ToolDb[ToolList[Index]]: - if String in [Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]: - List[Index] = String - NewKey = '%s_%s_%s_%s_%s' % tuple(List) - if NewKey not in BuildOption: - BuildOption[NewKey] = BuildOption[Key] - continue - del BuildOption[Key] - elif List[Index] not in ToolDb[ToolList[Index]]: - del BuildOption[Key] - if BuildOption: - if not KeyList: - for Op in BuildOption: - if NameGuid == BuildOption[Op]: - KeyList = Op.split('_') - Key = KeyList[0] + '_' + KeyList[1] +'_' + KeyList[2] - if Key in KeyStringList and KeyList[4] == DataType.TAB_GUID: - ToolPathKey = Key + '_' + KeyList[3] + '_PATH' - ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS' - if ToolPathKey in BuildOption: - ToolPathTmp = BuildOption[ToolPathKey] - if ToolOptionKey in BuildOption: - ToolOption = BuildOption[ToolOptionKey] - + 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 diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py index e5693c0d27..037493f0b0 100755 --- a/BaseTools/Source/Python/build/build.py +++ b/BaseTools/Source/Python/build/build.py @@ -62,6 +62,7 @@ from AutoGen.ModuleAutoGenHelper import WorkSpaceInfo, PlatformInfo from GenFds.FdfParser import FdfParser from AutoGen.IncludesAutoGen import IncludesAutoGen from GenFds.GenFds import resetFdsGlobalVariable +from AutoGen.AutoGen import CalculatePriorityValue ## standard targets of build command gSupportedTarget = ['all', 'genc', 'genmake', 'modules', 'libraries', 'fds', 'clean', 'cleanall', 'cleanlib', 'run'] @@ -2425,27 +2426,42 @@ class Build(): FvDir = Wa.FvDir if not os.path.exists(FvDir): continue - for Arch in self.ArchList: - # Look through the tool definitions for GUIDed tools + guidList = [] + tooldefguidList = [] guidAttribs = [] - for (attrib, value) in self.ToolDef.ToolsDefTxtDictionary.items(): - GuidBuildTarget, GuidToolChain, GuidArch, GuidTool, GuidAttr = attrib.split('_') - if GuidAttr.upper() == 'GUID': - if GuidBuildTarget == TAB_STAR: - GuidBuildTarget = BuildTarget - if GuidToolChain == TAB_STAR: - GuidToolChain = ToolChain - if GuidArch == TAB_STAR: - GuidArch = Arch - if GuidBuildTarget == BuildTarget and GuidToolChain == ToolChain and GuidArch == Arch: - path = '_'.join(attrib.split('_')[:-1]) + '_PATH' - if path in self.ToolDef.ToolsDefTxtDictionary: - path = self.ToolDef.ToolsDefTxtDictionary[path] - path = self.GetRealPathOfTool(path) - guidAttribs.append((value.lower(), GuidTool, path)) + for Platform in Wa.AutoGenObjectList: + if Platform.BuildTarget != BuildTarget: + continue + if Platform.ToolChain != ToolChain: + continue + if Platform.Arch != Arch: + continue + if hasattr (Platform, 'BuildOption'): + for Tool in Platform.BuildOption: + if 'GUID' in Platform.BuildOption[Tool]: + if 'PATH' in Platform.BuildOption[Tool]: + value = Platform.BuildOption[Tool]['GUID'] + if value in guidList: + EdkLogger.error("build", FORMAT_INVALID, "Duplicate GUID value %s used with Tool %s in DSC [BuildOptions]." % (value, Tool)) + path = Platform.BuildOption[Tool]['PATH'] + guidList.append(value) + guidAttribs.append((value, Tool, path)) + for Tool in Platform.ToolDefinition: + if 'GUID' in Platform.ToolDefinition[Tool]: + if 'PATH' in Platform.ToolDefinition[Tool]: + value = Platform.ToolDefinition[Tool]['GUID'] + if value in tooldefguidList: + EdkLogger.error("build", FORMAT_INVALID, "Duplicate GUID value %s used with Tool %s in tools_def.txt." % (value, Tool)) + tooldefguidList.append(value) + if value in guidList: + # Already added by platform + continue + path = Platform.ToolDefinition[Tool]['PATH'] + guidList.append(value) + guidAttribs.append((value, Tool, path)) # Sort by GuidTool name - sorted (guidAttribs, key=lambda x: x[1]) + guidAttribs = sorted (guidAttribs, key=lambda x: x[1]) # Write out GuidedSecTools.txt toolsFile = os.path.join(FvDir, 'GuidedSectionTools.txt') toolsFile = open(toolsFile, 'wt') -- 2.39.2