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 <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Yuwei Chen <yuwei.chen@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Bob Feng <bob.c.feng@intel.com>
This commit is contained in:
Michael D Kinney 2021-05-07 08:40:29 -07:00 committed by mergify[bot]
parent 375f2d8e68
commit ef3840c1ff
3 changed files with 190 additions and 97 deletions

View File

@ -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":

View File

@ -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

View File

@ -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')