public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Michael D Kinney" <michael.d.kinney@intel.com>
To: devel@edk2.groups.io
Cc: Bob Feng <bob.c.feng@intel.com>,
	Liming Gao <gaoliming@byosoft.com.cn>,
	Yuwei Chen <yuwei.chen@intel.com>
Subject: [Patch 1/1] BaseTools: Fix DSC override of Guided tool
Date: Sat,  8 May 2021 12:42:50 -0700	[thread overview]
Message-ID: <20210508194250.310-1-michael.d.kinney@intel.com> (raw)

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>
---
 .../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 832c0da86bb7..592d4824a4b3 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 c31fc24870d5..25f9d54874d3 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 e5693c0d27a2..037493f0b02a 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.31.1.windows.1


             reply	other threads:[~2021-05-08 19:43 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-08 19:42 Michael D Kinney [this message]
2021-05-10  1:20 ` [Patch 1/1] BaseTools: Fix DSC override of Guided tool Bob Feng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210508194250.310-1-michael.d.kinney@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox