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]: if Tool in self._BuildOptionWithToolDef(RetVal) and Attr in self._BuildOptionWithToolDef(RetVal)[Tool]:
# check if override is indicated # check if override is indicated
if self._BuildOptionWithToolDef(RetVal)[Tool][Attr].startswith('='): if self._BuildOptionWithToolDef(RetVal)[Tool][Attr].startswith('='):
Value = self._BuildOptionWithToolDef(RetVal)[Tool][Attr][1:] Value = self._BuildOptionWithToolDef(RetVal)[Tool][Attr][1:].strip()
else: else:
if Attr != 'PATH': # Do not append PATH or GUID
if Attr != 'PATH' and Attr != 'GUID':
Value += " " + self._BuildOptionWithToolDef(RetVal)[Tool][Attr] Value += " " + self._BuildOptionWithToolDef(RetVal)[Tool][Attr]
else: else:
Value = self._BuildOptionWithToolDef(RetVal)[Tool][Attr] 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": if Attr == "PATH":
# Don't put MAKE definition in the file # Don't put MAKE definition in the file
if Tool != "MAKE": if Tool != "MAKE":

View File

@ -32,6 +32,7 @@ from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws from Common.MultipleWorkspace import MultipleWorkspace as mws
import Common.GlobalData as GlobalData import Common.GlobalData as GlobalData
from Common.BuildToolError import * from Common.BuildToolError import *
from AutoGen.AutoGen import CalculatePriorityValue
## Global variables ## Global variables
# #
@ -850,6 +851,10 @@ class GenFdsGlobalVariable:
# @param NameGuid The Guid name # @param NameGuid The Guid name
# #
def FindExtendTool(KeyStringList, CurrentArchList, NameGuid): 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"))) ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))
ToolDef = ToolDefObj.ToolDef ToolDef = ToolDefObj.ToolDef
ToolDb = ToolDef.ToolsDefTxtDatabase ToolDb = ToolDef.ToolsDefTxtDatabase
@ -864,86 +869,159 @@ def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
if Target + '_' + ToolChain + '_' + Arch not in KeyStringList: if Target + '_' + ToolChain + '_' + Arch not in KeyStringList:
KeyStringList.append(Target + '_' + ToolChain + '_' + Arch) KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)
if GenFdsGlobalVariable.GuidToolDefinition:
if NameGuid in GenFdsGlobalVariable.GuidToolDefinition:
return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]
ToolDefinition = ToolDef.ToolsDefTxtDictionary
ToolPathTmp = None ToolPathTmp = None
ToolOption = None ToolOption = None
ToolPathKey = None for Arch in CurrentArchList:
ToolOptionKey = None MatchItem = None
KeyList = None MatchPathItem = None
for tool_def in ToolDefinition.items(): MatchOptionsItem = None
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 KeyString in KeyStringList: for KeyString in KeyStringList:
KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_') KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')
if KeyList[0] == DataType.TAB_STAR: if KeyStringArch != Arch:
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))
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 continue
del BuildOption[Key] for Item in ToolDef.ToolsDefTxtDictionary:
elif List[Index] not in ToolDb[ToolList[Index]]: if len(Item.split('_')) < 5:
del BuildOption[Key] continue
if BuildOption: ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_')
if not KeyList: if ItemTarget == DataType.TAB_STAR:
for Op in BuildOption: ItemTarget = KeyStringBuildTarget
if NameGuid == BuildOption[Op]: if ItemToolChain == DataType.TAB_STAR:
KeyList = Op.split('_') ItemToolChain = KeyStringToolChain
Key = KeyList[0] + '_' + KeyList[1] +'_' + KeyList[2] if ItemArch == DataType.TAB_STAR:
if Key in KeyStringList and KeyList[4] == DataType.TAB_GUID: ItemArch = KeyStringArch
ToolPathKey = Key + '_' + KeyList[3] + '_PATH' if ItemTarget != KeyStringBuildTarget:
ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS' continue
if ToolPathKey in BuildOption: if ItemToolChain != KeyStringToolChain:
ToolPathTmp = BuildOption[ToolPathKey] continue
if ToolOptionKey in BuildOption: if ItemArch != KeyStringArch:
ToolOption = BuildOption[ToolOptionKey] 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) GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption)
return ToolPathTmp, ToolOption return ToolPathTmp, ToolOption

View File

@ -62,6 +62,7 @@ from AutoGen.ModuleAutoGenHelper import WorkSpaceInfo, PlatformInfo
from GenFds.FdfParser import FdfParser from GenFds.FdfParser import FdfParser
from AutoGen.IncludesAutoGen import IncludesAutoGen from AutoGen.IncludesAutoGen import IncludesAutoGen
from GenFds.GenFds import resetFdsGlobalVariable from GenFds.GenFds import resetFdsGlobalVariable
from AutoGen.AutoGen import CalculatePriorityValue
## standard targets of build command ## standard targets of build command
gSupportedTarget = ['all', 'genc', 'genmake', 'modules', 'libraries', 'fds', 'clean', 'cleanall', 'cleanlib', 'run'] gSupportedTarget = ['all', 'genc', 'genmake', 'modules', 'libraries', 'fds', 'clean', 'cleanall', 'cleanlib', 'run']
@ -2425,27 +2426,42 @@ class Build():
FvDir = Wa.FvDir FvDir = Wa.FvDir
if not os.path.exists(FvDir): if not os.path.exists(FvDir):
continue continue
for Arch in self.ArchList: for Arch in self.ArchList:
# Look through the tool definitions for GUIDed tools guidList = []
tooldefguidList = []
guidAttribs = [] guidAttribs = []
for (attrib, value) in self.ToolDef.ToolsDefTxtDictionary.items(): for Platform in Wa.AutoGenObjectList:
GuidBuildTarget, GuidToolChain, GuidArch, GuidTool, GuidAttr = attrib.split('_') if Platform.BuildTarget != BuildTarget:
if GuidAttr.upper() == 'GUID': continue
if GuidBuildTarget == TAB_STAR: if Platform.ToolChain != ToolChain:
GuidBuildTarget = BuildTarget continue
if GuidToolChain == TAB_STAR: if Platform.Arch != Arch:
GuidToolChain = ToolChain continue
if GuidArch == TAB_STAR: if hasattr (Platform, 'BuildOption'):
GuidArch = Arch for Tool in Platform.BuildOption:
if GuidBuildTarget == BuildTarget and GuidToolChain == ToolChain and GuidArch == Arch: if 'GUID' in Platform.BuildOption[Tool]:
path = '_'.join(attrib.split('_')[:-1]) + '_PATH' if 'PATH' in Platform.BuildOption[Tool]:
if path in self.ToolDef.ToolsDefTxtDictionary: value = Platform.BuildOption[Tool]['GUID']
path = self.ToolDef.ToolsDefTxtDictionary[path] if value in guidList:
path = self.GetRealPathOfTool(path) EdkLogger.error("build", FORMAT_INVALID, "Duplicate GUID value %s used with Tool %s in DSC [BuildOptions]." % (value, Tool))
guidAttribs.append((value.lower(), GuidTool, path)) 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 # Sort by GuidTool name
sorted (guidAttribs, key=lambda x: x[1]) guidAttribs = sorted (guidAttribs, key=lambda x: x[1])
# Write out GuidedSecTools.txt # Write out GuidedSecTools.txt
toolsFile = os.path.join(FvDir, 'GuidedSectionTools.txt') toolsFile = os.path.join(FvDir, 'GuidedSectionTools.txt')
toolsFile = open(toolsFile, 'wt') toolsFile = open(toolsFile, 'wt')