]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools/Source/Python: New Target/ToolChain/Arch in DSC [BuildOptions]
authorMichael D Kinney <michael.d.kinney@intel.com>
Wed, 21 Apr 2021 06:12:51 +0000 (23:12 -0700)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 29 Apr 2021 07:29:17 +0000 (07:29 +0000)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3359

Update BaseTools to support new build targets, new tool chains,
and new architectures declared in DSC file [BuildOptions] sections.

* Do not expand * when tools_def.txt is parsed.  Only expand when
  both tools_def.txt and DSC [BuilsOptions] sections have been parsed.
  This also requires more flexible matching of tool keys that contain *
  in tool key fields.

* Pre-scan the platform DSC file for FAMILY and TOOLCHAIN declarations
  DSC in [BuildOptions] sections before the FAMILY and TOOLCHAIN need
  to be known.

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>
BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
BaseTools/Source/Python/Common/ToolDefClassObject.py
BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
BaseTools/Source/Python/build/build.py

index 7477b1d77fb8d92a8a7fde037a33e2fac925bcd1..167bb59d231528d345c593fd2626b2a4770ed4e4 100644 (file)
@@ -173,17 +173,30 @@ class AutoGenInfo(object):
             Family = Key[0]\r
             Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
             # if tool chain family doesn't match, skip it\r
-            if Tool in ToolDef and Family != "":\r
-                FamilyIsNull = False\r
-                if ToolDef[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":\r
-                    if Family != ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
-                        continue\r
-                else:\r
-                    if ToolDef[Tool].get(TAB_TOD_DEFINES_FAMILY, "") == "":\r
-                        continue\r
-                    if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:\r
-                        continue\r
-                FamilyMatch = True\r
+            if Family != "":\r
+                Found = False\r
+                if Tool in ToolDef:\r
+                    FamilyIsNull = False\r
+                    if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[Tool]:\r
+                        if Family == ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
+                            FamilyMatch = True\r
+                            Found = True\r
+                    if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:\r
+                        if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:\r
+                            FamilyMatch = True\r
+                            Found = True\r
+                if TAB_STAR in ToolDef:\r
+                    FamilyIsNull = False\r
+                    if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[TAB_STAR]:\r
+                        if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
+                            FamilyMatch = True\r
+                            Found = True\r
+                    if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:\r
+                        if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:\r
+                            FamilyMatch = True\r
+                            Found = True\r
+                if not Found:\r
+                    continue\r
             # expand any wildcard\r
             if Target == TAB_STAR or Target == self.BuildTarget:\r
                 if Tag == TAB_STAR or Tag == self.ToolChain:\r
@@ -213,12 +226,19 @@ class AutoGenInfo(object):
             Family = Key[0]\r
             Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
             # if tool chain family doesn't match, skip it\r
-            if Tool not in ToolDef or Family == "":\r
+            if Family == "":\r
                 continue\r
             # option has been added before\r
-            if TAB_TOD_DEFINES_FAMILY not in ToolDef[Tool]:\r
-                continue\r
-            if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:\r
+            Found = False\r
+            if Tool in ToolDef:\r
+                if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:\r
+                    if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:\r
+                        Found = True\r
+            if TAB_STAR in ToolDef:\r
+                if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:\r
+                    if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:\r
+                        Found = True\r
+            if not Found:\r
                 continue\r
 \r
             # expand any wildcard\r
index e2ef3256773e1eceb65393eaf8eb3f58ca9701c7..21e72438e59e83b430f25b81007fa1d21673a671 100644 (file)
@@ -827,6 +827,33 @@ class PlatformAutoGen(AutoGen):
                 RetVal = RetVal + _SplitOption(Flags.strip())\r
         return RetVal\r
 \r
+    ## Compute a tool defintion key priority value in range 0..15\r
+    #\r
+    #  TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE  15\r
+    #  ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE  14\r
+    #  TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE  13\r
+    #  ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE  12\r
+    #  TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE  11\r
+    #  ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE  10\r
+    #  TARGET_*********_****_COMMANDTYPE_ATTRIBUTE   9\r
+    #  ******_*********_****_COMMANDTYPE_ATTRIBUTE   8\r
+    #  TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE   7\r
+    #  ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE   6\r
+    #  TARGET_*********_ARCH_***********_ATTRIBUTE   5\r
+    #  ******_*********_ARCH_***********_ATTRIBUTE   4\r
+    #  TARGET_TOOLCHAIN_****_***********_ATTRIBUTE   3\r
+    #  ******_TOOLCHAIN_****_***********_ATTRIBUTE   2\r
+    #  TARGET_*********_****_***********_ATTRIBUTE   1\r
+    #  ******_*********_****_***********_ATTRIBUTE   0\r
+    #\r
+    def ToolDefinitionPriority (self,Key):\r
+        KeyList = Key.split('_')\r
+        Priority = 0\r
+        for Index in range (0, min(4, len(KeyList))):\r
+            if KeyList[Index] != '*':\r
+                Priority += (1 << Index)\r
+        return Priority\r
+\r
     ## Get tool chain definition\r
     #\r
     #  Get each tool definition for given tool chain from tools_def.txt and platform\r
@@ -839,8 +866,16 @@ class PlatformAutoGen(AutoGen):
                             ExtraData="[%s]" % self.MetaFile)\r
         RetVal = OrderedDict()\r
         DllPathList = set()\r
-        for Def in ToolDefinition:\r
+\r
+        PrioritizedDefList = sorted(ToolDefinition.keys(), key=self.ToolDefinitionPriority, reverse=True)\r
+        for Def in PrioritizedDefList:\r
             Target, Tag, Arch, Tool, Attr = Def.split("_")\r
+            if Target == TAB_STAR:\r
+                Target = self.BuildTarget\r
+            if Tag == TAB_STAR:\r
+                Tag = self.ToolChain\r
+            if Arch == TAB_STAR:\r
+                Arch = self.Arch\r
             if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:\r
                 continue\r
 \r
@@ -850,9 +885,14 @@ class PlatformAutoGen(AutoGen):
                 DllPathList.add(Value)\r
                 continue\r
 \r
+            #\r
+            # ToolDefinition is sorted from highest priority to lowest priority.\r
+            # Only add the first(highest priority) match to RetVal\r
+            #\r
             if Tool not in RetVal:\r
                 RetVal[Tool] = OrderedDict()\r
-            RetVal[Tool][Attr] = Value\r
+            if Attr not in RetVal[Tool]:\r
+                RetVal[Tool][Attr] = Value\r
 \r
         ToolsDef = ''\r
         if GlobalData.gOptions.SilentMode and "MAKE" in RetVal:\r
@@ -860,9 +900,21 @@ class PlatformAutoGen(AutoGen):
                 RetVal["MAKE"]["FLAGS"] = ""\r
             RetVal["MAKE"]["FLAGS"] += " -s"\r
         MakeFlags = ''\r
-        for Tool in RetVal:\r
-            for Attr in RetVal[Tool]:\r
-                Value = RetVal[Tool][Attr]\r
+\r
+        ToolList = list(RetVal.keys())\r
+        ToolList.sort()\r
+        for Tool in ToolList:\r
+            if Tool == TAB_STAR:\r
+                continue\r
+            AttrList = list(RetVal[Tool].keys())\r
+            if TAB_STAR in ToolList:\r
+                AttrList += list(RetVal[TAB_STAR])\r
+            AttrList.sort()\r
+            for Attr in AttrList:\r
+                if Attr in RetVal[Tool]:\r
+                    Value = RetVal[Tool][Attr]\r
+                else:\r
+                    Value = RetVal[TAB_STAR][Attr]\r
                 if Tool in self._BuildOptionWithToolDef(RetVal) and Attr in self._BuildOptionWithToolDef(RetVal)[Tool]:\r
                     # check if override is indicated\r
                     if self._BuildOptionWithToolDef(RetVal)[Tool][Attr].startswith('='):\r
@@ -877,7 +929,7 @@ class PlatformAutoGen(AutoGen):
                 if Attr == "PATH":\r
                     # Don't put MAKE definition in the file\r
                     if Tool != "MAKE":\r
-                        ToolsDef += "%s = %s\n" % (Tool, Value)\r
+                        ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)\r
                 elif Attr != "DLL":\r
                     # Don't put MAKE definition in the file\r
                     if Tool == "MAKE":\r
@@ -1469,17 +1521,31 @@ class PlatformAutoGen(AutoGen):
             Family = Key[0]\r
             Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
             # if tool chain family doesn't match, skip it\r
-            if Tool in ToolDef and Family != "":\r
-                FamilyIsNull = False\r
-                if ToolDef[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":\r
-                    if Family != ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
-                        continue\r
-                else:\r
-                    if ToolDef[Tool].get(TAB_TOD_DEFINES_FAMILY, "") == "":\r
-                        continue\r
-                    if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:\r
-                        continue\r
-                FamilyMatch = True\r
+            if Family != "":\r
+                Found = False\r
+                if Tool in ToolDef:\r
+                    FamilyIsNull = False\r
+                    if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[Tool]:\r
+                        if Family == ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
+                            FamilyMatch = True\r
+                            Found = True\r
+                    if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:\r
+                        if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:\r
+                            FamilyMatch = True\r
+                            Found = True\r
+                if TAB_STAR in ToolDef:\r
+                    FamilyIsNull = False\r
+                    if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[TAB_STAR]:\r
+                        if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
+                            FamilyMatch = True\r
+                            Found = True\r
+                    if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:\r
+                        if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:\r
+                            FamilyMatch = True\r
+                            Found = True\r
+                if not Found:\r
+                    continue\r
+\r
             # expand any wildcard\r
             if Target == TAB_STAR or Target == self.BuildTarget:\r
                 if Tag == TAB_STAR or Tag == self.ToolChain:\r
@@ -1509,12 +1575,19 @@ class PlatformAutoGen(AutoGen):
             Family = Key[0]\r
             Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
             # if tool chain family doesn't match, skip it\r
-            if Tool not in ToolDef or Family == "":\r
+            if Family == "":\r
                 continue\r
             # option has been added before\r
-            if TAB_TOD_DEFINES_FAMILY not in ToolDef[Tool]:\r
-                continue\r
-            if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:\r
+            Found = False\r
+            if Tool in ToolDef:\r
+                if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:\r
+                    if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:\r
+                        Found = True\r
+            if TAB_STAR in ToolDef:\r
+                if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:\r
+                    if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:\r
+                        Found = True\r
+            if not Found:\r
                 continue\r
 \r
             # expand any wildcard\r
index 8e70407cb9e94a1562332739873d6fc11e7934f4..2b4b23849196199a8715efc46e8c9f0087557488 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to define each component of tools_def.txt file\r
 #\r
-# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>\r
 # SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 \r
@@ -86,23 +86,6 @@ class ToolDefClassObject(object):
         self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH].sort()\r
         self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE].sort()\r
 \r
-        KeyList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH, TAB_TOD_DEFINES_COMMAND_TYPE]\r
-        for Index in range(3, -1, -1):\r
-            # make a copy of the keys to enumerate over to prevent issues when\r
-            # adding/removing items from the original dict.\r
-            for Key in list(self.ToolsDefTxtDictionary.keys()):\r
-                List = Key.split('_')\r
-                if List[Index] == TAB_STAR:\r
-                    for String in self.ToolsDefTxtDatabase[KeyList[Index]]:\r
-                        List[Index] = String\r
-                        NewKey = '%s_%s_%s_%s_%s' % tuple(List)\r
-                        if NewKey not in self.ToolsDefTxtDictionary:\r
-                            self.ToolsDefTxtDictionary[NewKey] = self.ToolsDefTxtDictionary[Key]\r
-                    del self.ToolsDefTxtDictionary[Key]\r
-                elif List[Index] not in self.ToolsDefTxtDatabase[KeyList[Index]]:\r
-                    del self.ToolsDefTxtDictionary[Key]\r
-\r
-\r
     ## IncludeToolDefFile\r
     #\r
     # Load target.txt file and parse it as if its contents were inside the main file\r
index 3019ec63c3bb8f757e284c58c121079d1542428f..c31fc24870d56b495240f2daca7b9b87ad32291f 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Global variables for GenFds\r
 #\r
-#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
@@ -875,14 +875,27 @@ def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
     ToolOptionKey = None\r
     KeyList = None\r
     for tool_def in ToolDefinition.items():\r
-        if NameGuid.lower() == tool_def[1].lower():\r
-            KeyList = tool_def[0].split('_')\r
-            Key = KeyList[0] + \\r
-                  '_' + \\r
-                  KeyList[1] + \\r
-                  '_' + \\r
-                  KeyList[2]\r
-            if Key in KeyStringList and KeyList[4] == DataType.TAB_GUID:\r
+        KeyList = tool_def[0].split('_')\r
+        if len(KeyList) < 5:\r
+            continue\r
+        if KeyList[4] != DataType.TAB_GUID:\r
+            continue\r
+        if NameGuid.lower() != tool_def[1].lower():\r
+            continue\r
+        Key = KeyList[0] + \\r
+                '_' + \\r
+                KeyList[1] + \\r
+                '_' + \\r
+                KeyList[2]\r
+        for KeyString in KeyStringList:\r
+            KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')\r
+            if KeyList[0] == DataType.TAB_STAR:\r
+                KeyList[0] = KeyStringBuildTarget\r
+            if KeyList[1] == DataType.TAB_STAR:\r
+                KeyList[1] = KeyStringToolChain\r
+            if KeyList[2] == DataType.TAB_STAR:\r
+                KeyList[2] = KeyStringArch\r
+            if KeyList[0] == KeyStringBuildTarget and KeyList[1] == KeyStringToolChain and KeyList[2] == KeyStringArch:\r
                 ToolPathKey   = Key + '_' + KeyList[3] + '_PATH'\r
                 ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'\r
                 ToolPath = ToolDefinition.get(ToolPathKey)\r
index c4cfe38ad96af90e6d0f481e8f8d0dd64b3f0728..0570c29f1ada4779d65ea87e8289b476131c2c63 100755 (executable)
@@ -2,7 +2,7 @@
 # build a platform or a module\r
 #\r
 #  Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>\r
-#  Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>\r
 #  Copyright (c) 2018, Hewlett Packard Enterprise Development, L.P.<BR>\r
 #  Copyright (c) 2020, ARM Limited. All rights reserved.<BR>\r
 #\r
@@ -889,6 +889,47 @@ class Build():
         except:\r
             return False, UNKNOWN_ERROR\r
 \r
+    ## Add TOOLCHAIN and FAMILY declared in DSC [BuildOptions] to ToolsDefTxtDatabase.\r
+    #\r
+    # Loop through the set of build targets, tool chains, and archs provided on either\r
+    # the command line or in target.txt to discover FAMILY and TOOLCHAIN delclarations\r
+    # in [BuildOptions] sections that may be within !if expressions that may use\r
+    # $(TARGET), $(TOOLCHAIN), $(TOOLCHAIN_TAG), or $(ARCH) operands.\r
+    #\r
+    def GetToolChainAndFamilyFromDsc (self, File):\r
+        for BuildTarget in self.BuildTargetList:\r
+            GlobalData.gGlobalDefines['TARGET'] = BuildTarget\r
+            for BuildToolChain in self.ToolChainList:\r
+                GlobalData.gGlobalDefines['TOOLCHAIN']      = BuildToolChain\r
+                GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = BuildToolChain\r
+                for BuildArch in self.ArchList:\r
+                    GlobalData.gGlobalDefines['ARCH'] = BuildArch\r
+                    dscobj = self.BuildDatabase[File, BuildArch]\r
+                    for KeyFamily, Key, KeyCodeBase in dscobj.BuildOptions:\r
+                        try:\r
+                            Target, ToolChain, Arch, Tool, Attr = Key.split('_')\r
+                        except:\r
+                            continue\r
+                        if ToolChain == TAB_STAR or Attr != TAB_TOD_DEFINES_FAMILY:\r
+                            continue\r
+                        try:\r
+                            Family = dscobj.BuildOptions[(KeyFamily, Key, KeyCodeBase)]\r
+                            Family = Family.strip().strip('=').strip()\r
+                        except:\r
+                            continue\r
+                        if TAB_TOD_DEFINES_FAMILY not in self.ToolDef.ToolsDefTxtDatabase:\r
+                            self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY] = {}\r
+                        if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY]:\r
+                            self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][ToolChain] = Family\r
+                        if TAB_TOD_DEFINES_BUILDRULEFAMILY not in self.ToolDef.ToolsDefTxtDatabase:\r
+                            self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY] = {}\r
+                        if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
+                            self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][ToolChain] = Family\r
+                        if TAB_TOD_DEFINES_TOOL_CHAIN_TAG not in self.ToolDef.ToolsDefTxtDatabase:\r
+                            self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] = []\r
+                        if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG]:\r
+                            self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG].append(ToolChain)\r
+\r
     ## Load configuration\r
     #\r
     #   This method will parse target.txt and get the build configurations.\r
@@ -910,6 +951,26 @@ class Build():
             if self.ToolChainList is None or len(self.ToolChainList) == 0:\r
                 EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.\n")\r
 \r
+        if not self.PlatformFile:\r
+            PlatformFile = self.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_ACTIVE_PLATFORM]\r
+            if not PlatformFile:\r
+                # Try to find one in current directory\r
+                WorkingDirectory = os.getcwd()\r
+                FileList = glob.glob(os.path.normpath(os.path.join(WorkingDirectory, '*.dsc')))\r
+                FileNum = len(FileList)\r
+                if FileNum >= 2:\r
+                    EdkLogger.error("build", OPTION_MISSING,\r
+                                    ExtraData="There are %d DSC files in %s. Use '-p' to specify one.\n" % (FileNum, WorkingDirectory))\r
+                elif FileNum == 1:\r
+                    PlatformFile = FileList[0]\r
+                else:\r
+                    EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,\r
+                                    ExtraData="No active platform specified in target.txt or command line! Nothing can be built.\n")\r
+\r
+            self.PlatformFile = PathClass(NormFile(PlatformFile, self.WorkspaceDir), self.WorkspaceDir)\r
+\r
+        self.GetToolChainAndFamilyFromDsc (self.PlatformFile)\r
+\r
         # check if the tool chains are defined or not\r
         NewToolChainList = []\r
         for ToolChain in self.ToolChainList:\r
@@ -935,23 +996,6 @@ class Build():
                 ToolChainFamily.append(ToolDefinition[TAB_TOD_DEFINES_FAMILY][Tool])\r
         self.ToolChainFamily = ToolChainFamily\r
 \r
-        if not self.PlatformFile:\r
-            PlatformFile = self.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_ACTIVE_PLATFORM]\r
-            if not PlatformFile:\r
-                # Try to find one in current directory\r
-                WorkingDirectory = os.getcwd()\r
-                FileList = glob.glob(os.path.normpath(os.path.join(WorkingDirectory, '*.dsc')))\r
-                FileNum = len(FileList)\r
-                if FileNum >= 2:\r
-                    EdkLogger.error("build", OPTION_MISSING,\r
-                                    ExtraData="There are %d DSC files in %s. Use '-p' to specify one.\n" % (FileNum, WorkingDirectory))\r
-                elif FileNum == 1:\r
-                    PlatformFile = FileList[0]\r
-                else:\r
-                    EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,\r
-                                    ExtraData="No active platform specified in target.txt or command line! Nothing can be built.\n")\r
-\r
-            self.PlatformFile = PathClass(NormFile(PlatformFile, self.WorkspaceDir), self.WorkspaceDir)\r
         self.ThreadNumber   = ThreadNum()\r
     ## Initialize build configuration\r
     #\r
@@ -2381,24 +2425,25 @@ class Build():
                     continue\r
 \r
                 for Arch in self.ArchList:\r
-                    # Build up the list of supported architectures for this build\r
-                    prefix = '%s_%s_%s_' % (BuildTarget, ToolChain, Arch)\r
-\r
                     # Look through the tool definitions for GUIDed tools\r
                     guidAttribs = []\r
                     for (attrib, value) in self.ToolDef.ToolsDefTxtDictionary.items():\r
-                        if attrib.upper().endswith('_GUID'):\r
-                            split = attrib.split('_')\r
-                            thisPrefix = '_'.join(split[0:3]) + '_'\r
-                            if thisPrefix == prefix:\r
-                                guid = self.ToolDef.ToolsDefTxtDictionary[attrib]\r
-                                guid = guid.lower()\r
-                                toolName = split[3]\r
-                                path = '_'.join(split[0:4]) + '_PATH'\r
-                                path = self.ToolDef.ToolsDefTxtDictionary[path]\r
-                                path = self.GetRealPathOfTool(path)\r
-                                guidAttribs.append((guid, toolName, path))\r
-\r
+                        GuidBuildTarget, GuidToolChain, GuidArch, GuidTool, GuidAttr = attrib.split('_')\r
+                        if GuidAttr.upper() == 'GUID':\r
+                            if GuidBuildTarget == TAB_STAR:\r
+                                GuidBuildTarget = BuildTarget\r
+                            if GuidToolChain == TAB_STAR:\r
+                                GuidToolChain = ToolChain\r
+                            if GuidArch == TAB_STAR:\r
+                                GuidArch = Arch\r
+                            if GuidBuildTarget == BuildTarget and GuidToolChain == ToolChain and GuidArch == Arch:\r
+                                path = '_'.join(attrib.split('_')[:-1]) + '_PATH'\r
+                                if path in self.ToolDef.ToolsDefTxtDictionary:\r
+                                    path = self.ToolDef.ToolsDefTxtDictionary[path]\r
+                                    path = self.GetRealPathOfTool(path)\r
+                                    guidAttribs.append((value.lower(), GuidTool, path))\r
+                    # Sort by GuidTool name\r
+                    sorted (guidAttribs, key=lambda x: x[1])\r
                     # Write out GuidedSecTools.txt\r
                     toolsFile = os.path.join(FvDir, 'GuidedSectionTools.txt')\r
                     toolsFile = open(toolsFile, 'wt')\r