]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
BaseTools/Source/Python: New Target/ToolChain/Arch in DSC [BuildOptions]
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GenFdsGlobalVariable.py
index 052736b9d8c745f2ea14d723edb9a28f1ed6178c..c31fc24870d56b495240f2daca7b9b87ad32291f 100644 (file)
@@ -1,37 +1,37 @@
 ## @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
-#  This program and the accompanying materials\r
-#  are licensed and made available under the terms and conditions of the BSD License\r
-#  which accompanies this distribution.  The full text of the license may be found at\r
-#  http://opensource.org/licenses/bsd-license.php\r
-#\r
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 \r
 ##\r
 # Import Modules\r
 #\r
+from __future__ import print_function\r
+from __future__ import absolute_import\r
+\r
 import Common.LongFilePathOs as os\r
 import sys\r
-import subprocess\r
-import struct\r
-import array\r
+from sys import stdout\r
+from subprocess import PIPE,Popen\r
+from struct import Struct\r
+from array import array\r
 \r
-from Common.BuildToolError import *\r
+from Common.BuildToolError import COMMAND_FAILURE,GENFDS_ERROR\r
 from Common import EdkLogger\r
 from Common.Misc import SaveFileOnChange\r
 \r
-from Common.TargetTxtClassObject import TargetTxtClassObject\r
-from Common.ToolDefClassObject import ToolDefClassObject, ToolDefDict\r
-from AutoGen.BuildEngine import BuildRule\r
+from Common.TargetTxtClassObject import TargetTxtDict\r
+from Common.ToolDefClassObject import ToolDefDict\r
+from AutoGen.BuildEngine import ToolBuildRule\r
 import Common.DataType as DataType\r
-from Common.Misc import PathClass\r
+from Common.Misc import PathClass,CreateDirectory\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
 from Common.MultipleWorkspace import MultipleWorkspace as mws\r
+import Common.GlobalData as GlobalData\r
+from Common.BuildToolError import *\r
 \r
 ## Global variables\r
 #\r
@@ -47,13 +47,11 @@ class GenFdsGlobalVariable:
     WorkSpace = None\r
     WorkSpaceDir = ''\r
     ConfDir = ''\r
-    EdkSourceDir = ''\r
     OutputDirFromDscDict = {}\r
     TargetName = ''\r
     ToolChainTag = ''\r
     RuleDict = {}\r
     ArchList = None\r
-    VtfDict = {}\r
     ActivePlatform = None\r
     FvAddressFileName = ''\r
     VerboseMode = False\r
@@ -73,7 +71,7 @@ class GenFdsGlobalVariable:
     SecCmdList = []\r
     CopyList   = []\r
     ModuleFile = ''\r
-    EnableGenfdsMultiThread = False\r
+    EnableGenfdsMultiThread = True\r
 \r
     #\r
     # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.\r
@@ -88,7 +86,7 @@ class GenFdsGlobalVariable:
     EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'\r
     LARGE_FILE_SIZE = 0x1000000\r
 \r
-    SectionHeader = struct.Struct("3B 1B")\r
+    SectionHeader = Struct("3B 1B")\r
 \r
     # FvName, FdName, CapName in FDF, Image file name\r
     ImageBinDict = {}\r
@@ -96,34 +94,27 @@ class GenFdsGlobalVariable:
     ## LoadBuildRule\r
     #\r
     @staticmethod\r
-    def __LoadBuildRule():\r
+    def _LoadBuildRule():\r
         if GenFdsGlobalVariable.__BuildRuleDatabase:\r
             return GenFdsGlobalVariable.__BuildRuleDatabase\r
-        BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.ConfDir, "target.txt"))\r
-        TargetTxt = TargetTxtClassObject()\r
-        if os.path.isfile(BuildConfigurationFile) == True:\r
-            TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
-            if DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF in TargetTxt.TargetTxtDictionary:\r
-                BuildRuleFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
-            if not BuildRuleFile:\r
-                BuildRuleFile = 'Conf/build_rule.txt'\r
-            GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule(BuildRuleFile)\r
-            ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
-            if ToolDefinitionFile == '':\r
-                ToolDefinitionFile = "Conf/tools_def.txt"\r
-            if os.path.isfile(ToolDefinitionFile):\r
-                ToolDef = ToolDefClassObject()\r
-                ToolDef.LoadToolDefFile(ToolDefinitionFile)\r
-                ToolDefinition = ToolDef.ToolsDefTxtDatabase\r
-                if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \\r
-                   and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \\r
-                   and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:\r
-                    GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]\r
-\r
-                if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \\r
-                   and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \\r
-                   and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:\r
-                    GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]\r
+        BuildRule = ToolBuildRule()\r
+        GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule.ToolBuildRule\r
+        TargetObj = TargetTxtDict()\r
+        ToolDefinitionFile = TargetObj.Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
+        if ToolDefinitionFile == '':\r
+            ToolDefinitionFile = "Conf/tools_def.txt"\r
+        if os.path.isfile(ToolDefinitionFile):\r
+            ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))\r
+            ToolDefinition = ToolDefObj.ToolDef.ToolsDefTxtDatabase\r
+            if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \\r
+               and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \\r
+               and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:\r
+                GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]\r
+\r
+            if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \\r
+               and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \\r
+               and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:\r
+                GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]\r
         return GenFdsGlobalVariable.__BuildRuleDatabase\r
 \r
     ## GetBuildRules\r
@@ -138,43 +129,42 @@ class GenFdsGlobalVariable:
         if not Arch in GenFdsGlobalVariable.OutputDirDict:\r
             return {}\r
 \r
-        BuildRuleDatabase = GenFdsGlobalVariable.__LoadBuildRule()\r
+        BuildRuleDatabase = GenFdsGlobalVariable._LoadBuildRule()\r
         if not BuildRuleDatabase:\r
             return {}\r
 \r
         PathClassObj = PathClass(Inf.MetaFile.File,\r
                                  GenFdsGlobalVariable.WorkSpaceDir)\r
-        Macro = {}\r
-        Macro["WORKSPACE"             ] = GenFdsGlobalVariable.WorkSpaceDir\r
-        Macro["MODULE_NAME"           ] = Inf.BaseName\r
-        Macro["MODULE_GUID"           ] = Inf.Guid\r
-        Macro["MODULE_VERSION"        ] = Inf.Version\r
-        Macro["MODULE_TYPE"           ] = Inf.ModuleType\r
-        Macro["MODULE_FILE"           ] = str(PathClassObj)\r
-        Macro["MODULE_FILE_BASE_NAME" ] = PathClassObj.BaseName\r
-        Macro["MODULE_RELATIVE_DIR"   ] = PathClassObj.SubDir\r
-        Macro["MODULE_DIR"            ] = PathClassObj.SubDir\r
-\r
-        Macro["BASE_NAME"             ] = Inf.BaseName\r
-\r
-        Macro["ARCH"                  ] = Arch\r
-        Macro["TOOLCHAIN"             ] = GenFdsGlobalVariable.ToolChainTag\r
-        Macro["TOOLCHAIN_TAG"         ] = GenFdsGlobalVariable.ToolChainTag\r
-        Macro["TOOL_CHAIN_TAG"        ] = GenFdsGlobalVariable.ToolChainTag\r
-        Macro["TARGET"                ] = GenFdsGlobalVariable.TargetName\r
-\r
-        Macro["BUILD_DIR"             ] = GenFdsGlobalVariable.OutputDirDict[Arch]\r
-        Macro["BIN_DIR"               ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)\r
-        Macro["LIB_DIR"               ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)\r
         BuildDir = os.path.join(\r
             GenFdsGlobalVariable.OutputDirDict[Arch],\r
             Arch,\r
             PathClassObj.SubDir,\r
             PathClassObj.BaseName\r
         )\r
-        Macro["MODULE_BUILD_DIR"      ] = BuildDir\r
-        Macro["OUTPUT_DIR"            ] = os.path.join(BuildDir, "OUTPUT")\r
-        Macro["DEBUG_DIR"             ] = os.path.join(BuildDir, "DEBUG")\r
+        BinDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)\r
+        Macro = {\r
+        "WORKSPACE":GenFdsGlobalVariable.WorkSpaceDir,\r
+        "MODULE_NAME":Inf.BaseName,\r
+        "MODULE_GUID":Inf.Guid,\r
+        "MODULE_VERSION":Inf.Version,\r
+        "MODULE_TYPE":Inf.ModuleType,\r
+        "MODULE_FILE":str(PathClassObj),\r
+        "MODULE_FILE_BASE_NAME":PathClassObj.BaseName,\r
+        "MODULE_RELATIVE_DIR":PathClassObj.SubDir,\r
+        "MODULE_DIR":PathClassObj.SubDir,\r
+        "BASE_NAME":Inf.BaseName,\r
+        "ARCH":Arch,\r
+        "TOOLCHAIN":GenFdsGlobalVariable.ToolChainTag,\r
+        "TOOLCHAIN_TAG":GenFdsGlobalVariable.ToolChainTag,\r
+        "TOOL_CHAIN_TAG":GenFdsGlobalVariable.ToolChainTag,\r
+        "TARGET":GenFdsGlobalVariable.TargetName,\r
+        "BUILD_DIR":GenFdsGlobalVariable.OutputDirDict[Arch],\r
+        "BIN_DIR":BinDir,\r
+        "LIB_DIR":BinDir,\r
+        "MODULE_BUILD_DIR":BuildDir,\r
+        "OUTPUT_DIR":os.path.join(BuildDir, "OUTPUT"),\r
+        "DEBUG_DIR":os.path.join(BuildDir, "DEBUG")\r
+        }\r
 \r
         BuildRules = {}\r
         for Type in BuildRuleDatabase.FileTypeList:\r
@@ -215,12 +205,12 @@ class GenFdsGlobalVariable:
 \r
         if not Inf.IsBinaryModule:\r
             for File in Inf.Sources:\r
-                if File.TagName in ("", "*", GenFdsGlobalVariable.ToolChainTag) and \\r
-                    File.ToolChainFamily in ("", "*", GenFdsGlobalVariable.ToolChainFamily):\r
+                if File.TagName in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainTag} and \\r
+                    File.ToolChainFamily in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainFamily}:\r
                     FileList.append((File, DataType.TAB_UNKNOWN_FILE))\r
 \r
         for File in Inf.Binaries:\r
-            if File.Target in [DataType.TAB_COMMON, '*', GenFdsGlobalVariable.TargetName]:\r
+            if File.Target in {DataType.TAB_COMMON, DataType.TAB_STAR, GenFdsGlobalVariable.TargetName}:\r
                 FileList.append((File, File.Type))\r
 \r
         for File, FileType in FileList:\r
@@ -232,7 +222,7 @@ class GenFdsGlobalVariable:
                 Source = SourceList[Index]\r
                 Index = Index + 1\r
 \r
-                if File.IsBinary and File == Source and Inf.Binaries is not None and File in Inf.Binaries:\r
+                if File.IsBinary and File == Source and Inf.Binaries and File in Inf.Binaries:\r
                     # Skip all files that are not binary libraries\r
                     if not Inf.LibraryClass:\r
                         continue\r
@@ -286,19 +276,18 @@ class GenFdsGlobalVariable:
     #   @param  Workspace           The directory of workspace\r
     #   @param  ArchList            The Arch list of platform\r
     #\r
+    @staticmethod\r
     def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):\r
-        GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir :%s" % OutputDir)\r
-#        GenFdsGlobalVariable.OutputDirDict = OutputDir\r
+        GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir:%s" % OutputDir)\r
         GenFdsGlobalVariable.FdfParser = FdfParser\r
         GenFdsGlobalVariable.WorkSpace = WorkSpace\r
         GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)\r
-        if not os.path.exists(GenFdsGlobalVariable.FvDir) :\r
+        if not os.path.exists(GenFdsGlobalVariable.FvDir):\r
             os.makedirs(GenFdsGlobalVariable.FvDir)\r
         GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
-        if not os.path.exists(GenFdsGlobalVariable.FfsDir) :\r
+        if not os.path.exists(GenFdsGlobalVariable.FfsDir):\r
             os.makedirs(GenFdsGlobalVariable.FfsDir)\r
 \r
-        T_CHAR_LF = '\n'\r
         #\r
         # Create FV Address inf file\r
         #\r
@@ -307,7 +296,7 @@ class GenFdsGlobalVariable:
         #\r
         # Add [Options]\r
         #\r
-        FvAddressFile.writelines("[options]" + T_CHAR_LF)\r
+        FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK)\r
         BsAddress = '0'\r
         for Arch in ArchList:\r
             if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:\r
@@ -316,19 +305,22 @@ class GenFdsGlobalVariable:
 \r
         FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r
                                        BsAddress + \\r
-                                       T_CHAR_LF)\r
+                                       DataType.TAB_LINE_BREAK)\r
 \r
         RtAddress = '0'\r
-        for Arch in ArchList:\r
-            if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress:\r
-                RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress\r
+        for Arch in reversed(ArchList):\r
+            temp = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress\r
+            if temp:\r
+                RtAddress = temp\r
+                break\r
 \r
         FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r
                                        RtAddress + \\r
-                                       T_CHAR_LF)\r
+                                       DataType.TAB_LINE_BREAK)\r
 \r
         FvAddressFile.close()\r
 \r
+    @staticmethod\r
     def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData):\r
         GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile\r
         GenFdsGlobalVariable.FdfParser = FdfParser\r
@@ -337,7 +329,6 @@ class GenFdsGlobalVariable:
         GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]\r
         GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"]\r
         GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform\r
-        GenFdsGlobalVariable.EdkSourceDir = GlobalData.gGlobalDefines["EDK_SOURCE"]\r
         GenFdsGlobalVariable.ConfDir  = GlobalData.gConfDirectory\r
         GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread\r
         for Arch in ArchList:\r
@@ -359,7 +350,6 @@ class GenFdsGlobalVariable:
         if not os.path.exists(GenFdsGlobalVariable.FfsDir):\r
             os.makedirs(GenFdsGlobalVariable.FfsDir)\r
 \r
-        T_CHAR_LF = '\n'\r
         #\r
         # Create FV Address inf file\r
         #\r
@@ -368,7 +358,7 @@ class GenFdsGlobalVariable:
         #\r
         # Add [Options]\r
         #\r
-        FvAddressFile.writelines("[options]" + T_CHAR_LF)\r
+        FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK)\r
         BsAddress = '0'\r
         for Arch in ArchList:\r
             BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
@@ -379,20 +369,20 @@ class GenFdsGlobalVariable:
 \r
         FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r
                                  BsAddress + \\r
-                                 T_CHAR_LF)\r
+                                 DataType.TAB_LINE_BREAK)\r
 \r
         RtAddress = '0'\r
-        for Arch in ArchList:\r
-            if GenFdsGlobalVariable.WorkSpace.BuildObject[\r
+        for Arch in reversed(ArchList):\r
+            temp = GenFdsGlobalVariable.WorkSpace.BuildObject[\r
                 GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],\r
-                GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress:\r
-                RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[\r
-                    GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],\r
-                    GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress\r
+                GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress\r
+            if temp:\r
+                RtAddress = temp\r
+                break\r
 \r
         FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r
                                  RtAddress + \\r
-                                 T_CHAR_LF)\r
+                                 DataType.TAB_LINE_BREAK)\r
 \r
         FvAddressFile.close()\r
 \r
@@ -400,6 +390,7 @@ class GenFdsGlobalVariable:
     #\r
     #   @param  String           String that may contain macro\r
     #\r
+    @staticmethod\r
     def ReplaceWorkspaceMacro(String):\r
         String = mws.handleWsMacro(String)\r
         Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)\r
@@ -423,7 +414,7 @@ class GenFdsGlobalVariable:
         if not os.path.exists(Output):\r
             return True\r
         # always update "Output" if no "Input" given\r
-        if Input is None or len(Input) == 0:\r
+        if not Input:\r
             return True\r
 \r
         # if fdf file is changed after the 'Output" is generated, update the 'Output'\r
@@ -448,9 +439,9 @@ class GenFdsGlobalVariable:
             Cmd += ("-s", Type)\r
         if CompressionType:\r
             Cmd += ("-c", CompressionType)\r
-        if Guid is not None:\r
+        if Guid:\r
             Cmd += ("-g", Guid)\r
-        if DummyFile is not None:\r
+        if DummyFile:\r
             Cmd += ("--dummy", DummyFile)\r
         if GuidHdrLen:\r
             Cmd += ("-l", GuidHdrLen)\r
@@ -472,13 +463,29 @@ class GenFdsGlobalVariable:
                 if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
                     GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
             else:\r
-                SectionData = array.array('B', [0, 0, 0, 0])\r
-                SectionData.fromstring(Ui.encode("utf_16_le"))\r
+                SectionData = array('B', [0, 0, 0, 0])\r
+                SectionData.fromlist(array('B',Ui.encode('utf-16-le')).tolist())\r
                 SectionData.append(0)\r
                 SectionData.append(0)\r
                 Len = len(SectionData)\r
                 GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)\r
-                SaveFileOnChange(Output, SectionData.tostring())\r
+\r
+\r
+                DirName = os.path.dirname(Output)\r
+                if not CreateDirectory(DirName):\r
+                    EdkLogger.error(None, FILE_CREATE_FAILURE, "Could not create directory %s" % DirName)\r
+                else:\r
+                    if DirName == '':\r
+                        DirName = os.getcwd()\r
+                    if not os.access(DirName, os.W_OK):\r
+                        EdkLogger.error(None, PERMISSION_FAILURE, "Do not have write permission on directory %s" % DirName)\r
+\r
+                try:\r
+                    with open(Output, "wb") as Fd:\r
+                        SectionData.tofile(Fd)\r
+                        Fd.flush()\r
+                except IOError as X:\r
+                    EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s' % X)\r
 \r
         elif Ver:\r
             Cmd += ("-n", Ver)\r
@@ -500,6 +507,10 @@ class GenFdsGlobalVariable:
 \r
             SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
             if IsMakefile:\r
+                if sys.platform == "win32":\r
+                    Cmd = ['if', 'exist', Input[0]] + Cmd\r
+                else:\r
+                    Cmd = ['-test', '-e', Input[0], "&&"] + Cmd\r
                 if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
                     GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
             elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r
@@ -541,7 +552,10 @@ class GenFdsGlobalVariable:
 \r
         Cmd += ("-o", Output)\r
         for I in range(0, len(Input)):\r
-            Cmd += ("-i", Input[I])\r
+            if MakefilePath:\r
+                Cmd += ("-oi", Input[I])\r
+            else:\r
+                Cmd += ("-i", Input[I])\r
             if SectionAlign and SectionAlign[I]:\r
                 Cmd += ("-n", SectionAlign[I])\r
 \r
@@ -633,7 +647,7 @@ class GenFdsGlobalVariable:
                         Revision=None, DeviceId=None, VendorId=None, IsMakefile=False):\r
         InputList = []\r
         Cmd = ["EfiRom"]\r
-        if len(EfiInput) > 0:\r
+        if EfiInput:\r
 \r
             if Compress:\r
                 Cmd.append("-ec")\r
@@ -644,7 +658,7 @@ class GenFdsGlobalVariable:
                 Cmd.append(EfiFile)\r
                 InputList.append (EfiFile)\r
 \r
-        if len(BinaryInput) > 0:\r
+        if BinaryInput:\r
             Cmd.append("-b")\r
             for BinFile in BinaryInput:\r
                 Cmd.append(BinFile)\r
@@ -655,13 +669,13 @@ class GenFdsGlobalVariable:
             return\r
         GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))\r
 \r
-        if ClassCode is not None:\r
+        if ClassCode:\r
             Cmd += ("-l", ClassCode)\r
-        if Revision is not None:\r
+        if Revision:\r
             Cmd += ("-r", Revision)\r
-        if DeviceId is not None:\r
+        if DeviceId:\r
             Cmd += ("-i", DeviceId)\r
-        if VendorId is not None:\r
+        if VendorId:\r
             Cmd += ("-f", VendorId)\r
 \r
         Cmd += ("-o", Output)\r
@@ -687,6 +701,7 @@ class GenFdsGlobalVariable:
         else:\r
             GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)\r
 \r
+    @staticmethod\r
     def CallExternalTool (cmd, errorMess, returnValue=[]):\r
 \r
         if type(cmd) not in (tuple, list):\r
@@ -700,19 +715,19 @@ class GenFdsGlobalVariable:
             cmd += ('-v',)\r
             GenFdsGlobalVariable.InfLogger (cmd)\r
         else:\r
-            sys.stdout.write ('#')\r
-            sys.stdout.flush()\r
+            stdout.write ('#')\r
+            stdout.flush()\r
             GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1\r
             if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:\r
-                sys.stdout.write('\n')\r
+                stdout.write('\n')\r
 \r
         try:\r
-            PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
+            PopenObject = Popen(' '.join(cmd), stdout=PIPE, stderr=PIPE, shell=True)\r
         except Exception as X:\r
             EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))\r
         (out, error) = PopenObject.communicate()\r
 \r
-        while PopenObject.returncode is None :\r
+        while PopenObject.returncode is None:\r
             PopenObject.wait()\r
         if returnValue != [] and returnValue[0] != 0:\r
             #get command return value\r
@@ -720,51 +735,57 @@ class GenFdsGlobalVariable:
             return\r
         if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:\r
             GenFdsGlobalVariable.InfLogger ("Return Value = %d" % PopenObject.returncode)\r
-            GenFdsGlobalVariable.InfLogger (out.decode(encoding='utf-8',errors='ignore'))\r
-            GenFdsGlobalVariable.InfLogger (error.decode(encoding='utf-8', errors='ignore'))\r
+            GenFdsGlobalVariable.InfLogger(out.decode(encoding='utf-8', errors='ignore'))\r
+            GenFdsGlobalVariable.InfLogger(error.decode(encoding='utf-8', errors='ignore'))\r
             if PopenObject.returncode != 0:\r
                 print("###", cmd)\r
                 EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)\r
 \r
+    @staticmethod\r
     def VerboseLogger (msg):\r
         EdkLogger.verbose(msg)\r
 \r
+    @staticmethod\r
     def InfLogger (msg):\r
         EdkLogger.info(msg)\r
 \r
+    @staticmethod\r
     def ErrorLogger (msg, File=None, Line=None, ExtraData=None):\r
         EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)\r
 \r
+    @staticmethod\r
     def DebugLogger (Level, msg):\r
         EdkLogger.debug(Level, msg)\r
 \r
-    ## ReplaceWorkspaceMacro()\r
+    ## MacroExtend()\r
     #\r
     #   @param  Str           String that may contain macro\r
     #   @param  MacroDict     Dictionary that contains macro value pair\r
     #\r
-    def MacroExtend (Str, MacroDict={}, Arch=DataType.TAB_COMMON):\r
-        if Str is None :\r
+    @staticmethod\r
+    def MacroExtend (Str, MacroDict=None, Arch=DataType.TAB_COMMON):\r
+        if Str is None:\r
             return None\r
 \r
-        Dict = {'$(WORKSPACE)'   : GenFdsGlobalVariable.WorkSpaceDir,\r
-                '$(EDK_SOURCE)'  : GenFdsGlobalVariable.EdkSourceDir,\r
+        Dict = {'$(WORKSPACE)': GenFdsGlobalVariable.WorkSpaceDir,\r
 #                '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,\r
-                '$(TARGET)' : GenFdsGlobalVariable.TargetName,\r
-                '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag,\r
-                '$(SPACE)' : ' '\r
+                '$(TARGET)': GenFdsGlobalVariable.TargetName,\r
+                '$(TOOL_CHAIN_TAG)': GenFdsGlobalVariable.ToolChainTag,\r
+                '$(SPACE)': ' '\r
                }\r
-        OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]\r
+\r
         if Arch != DataType.TAB_COMMON and Arch in GenFdsGlobalVariable.ArchList:\r
             OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]\r
+        else:\r
+            OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]\r
 \r
         Dict['$(OUTPUT_DIRECTORY)'] = OutputDir\r
 \r
-        if MacroDict is not None  and len (MacroDict) != 0:\r
+        if MacroDict:\r
             Dict.update(MacroDict)\r
 \r
         for key in Dict:\r
-            if Str.find(key) >= 0 :\r
+            if Str.find(key) >= 0:\r
                 Str = Str.replace (key, Dict[key])\r
 \r
         if Str.find('$(ARCH)') >= 0:\r
@@ -779,14 +800,17 @@ class GenFdsGlobalVariable:
     #\r
     #   @param  PcdPattern           pattern that labels a PCD.\r
     #\r
+    @staticmethod\r
     def GetPcdValue (PcdPattern):\r
-        if PcdPattern is None :\r
+        if PcdPattern is None:\r
             return None\r
-        PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.')\r
+        if PcdPattern.startswith('PCD('):\r
+            PcdPair = PcdPattern[4:].rstrip(')').strip().split('.')\r
+        else:\r
+            PcdPair = PcdPattern.strip().split('.')\r
         TokenSpace = PcdPair[0]\r
         TokenCName = PcdPair[1]\r
 \r
-        PcdValue = ''\r
         for Arch in GenFdsGlobalVariable.ArchList:\r
             Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
             PcdDict = Platform.Pcds\r
@@ -798,8 +822,7 @@ class GenFdsGlobalVariable:
                     if PcdObj.DatumType != DataType.TAB_VOID:\r
                         EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r
 \r
-                    PcdValue = PcdObj.DefaultValue\r
-                    return PcdValue\r
+                    return PcdObj.DefaultValue\r
 \r
             for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,\r
                                                                          Arch,\r
@@ -814,21 +837,9 @@ class GenFdsGlobalVariable:
                         if PcdObj.DatumType != DataType.TAB_VOID:\r
                             EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r
 \r
-                        PcdValue = PcdObj.DefaultValue\r
-                        return PcdValue\r
-\r
-        return PcdValue\r
+                        return PcdObj.DefaultValue\r
 \r
-    SetDir = staticmethod(SetDir)\r
-    SetEnv = staticmethod(SetEnv)\r
-    ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro)\r
-    CallExternalTool = staticmethod(CallExternalTool)\r
-    VerboseLogger = staticmethod(VerboseLogger)\r
-    InfLogger = staticmethod(InfLogger)\r
-    ErrorLogger = staticmethod(ErrorLogger)\r
-    DebugLogger = staticmethod(DebugLogger)\r
-    MacroExtend = staticmethod (MacroExtend)\r
-    GetPcdValue = staticmethod(GetPcdValue)\r
+        return ''\r
 \r
 ## FindExtendTool()\r
 #\r
@@ -839,7 +850,9 @@ class GenFdsGlobalVariable:
 #  @param  NameGuid         The Guid name\r
 #\r
 def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):\r
-    ToolDb = ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase\r
+    ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))\r
+    ToolDef = ToolDefObj.ToolDef\r
+    ToolDb = ToolDef.ToolsDefTxtDatabase\r
     # if user not specify filter, try to deduce it from global data.\r
     if KeyStringList is None or KeyStringList == []:\r
         Target = GenFdsGlobalVariable.TargetName\r
@@ -855,21 +868,34 @@ def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
         if NameGuid in GenFdsGlobalVariable.GuidToolDefinition:\r
             return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]\r
 \r
-    ToolDefinition = ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDictionary\r
+    ToolDefinition = ToolDef.ToolsDefTxtDictionary\r
     ToolPathTmp = None\r
     ToolOption = None\r
     ToolPathKey = None\r
     ToolOptionKey = None\r
     KeyList = None\r
-    for ToolDef in ToolDefinition.items():\r
-        if NameGuid.lower() == ToolDef[1].lower() :\r
-            KeyList = ToolDef[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
+    for tool_def in ToolDefinition.items():\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
@@ -894,7 +920,7 @@ def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
             for Index in range(2, -1, -1):\r
                 for Key in list(BuildOption.keys()):\r
                     List = Key.split('_')\r
-                    if List[Index] == '*':\r
+                    if List[Index] == DataType.TAB_STAR:\r
                         for String in ToolDb[ToolList[Index]]:\r
                             if String in [Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]:\r
                                 List[Index] = String\r