]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/AutoGen/GenMake.py
BaseTools:fixed the incorrect autogen makefile which cause build failure.
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / GenMake.py
index edbf24398755e0ecc38054b9ee590e45214e030a..3e770ad7c425d1e6b8db3f49d4bccd9ed4905a3c 100644 (file)
@@ -1,33 +1,30 @@
 ## @file\r
 # Create makefile for MS nmake and GNU make\r
 #\r
 ## @file\r
 # Create makefile for MS nmake and GNU make\r
 #\r
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\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
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 \r
 ## Import Modules\r
 #\r
 #\r
 \r
 ## Import Modules\r
 #\r
+from __future__ import absolute_import\r
 import Common.LongFilePathOs as os\r
 import sys\r
 import string\r
 import re\r
 import os.path as path\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
 import Common.LongFilePathOs as os\r
 import sys\r
 import string\r
 import re\r
 import os.path as path\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
-\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 from Common.BuildToolError import *\r
 from Common.Misc import *\r
 from Common.BuildToolError import *\r
 from Common.Misc import *\r
-from Common.String import *\r
-from BuildEngine import *\r
+from Common.StringUtils import *\r
+from .BuildEngine import *\r
 import Common.GlobalData as GlobalData\r
 import Common.GlobalData as GlobalData\r
+from collections import OrderedDict\r
+from Common.DataType import TAB_COMPILER_MSFT\r
 \r
 ## Regular expression for finding header file inclusions\r
 \r
 ## Regular expression for finding header file inclusions\r
-gIncludePattern = re.compile(r"^[ \t]*#?[ \t]*include(?:[ \t]*(?:\\(?:\r\n|\r|\n))*[ \t]*)*(?:\(?[\"<]?[ \t]*)([-\w.\\/() \t]+)(?:[ \t]*[\">]?\)?)", re.MULTILINE|re.UNICODE|re.IGNORECASE)\r
+gIncludePattern = re.compile(r"^[ \t]*[#%]?[ \t]*include(?:[ \t]*(?:\\(?:\r\n|\r|\n))*[ \t]*)*(?:\(?[\"<]?[ \t]*)([-\w.\\/() \t]+)(?:[ \t]*[\">]?\)?)", re.MULTILINE | re.UNICODE | re.IGNORECASE)\r
 \r
 ## Regular expression for matching macro used in header file inclusion\r
 gMacroPattern = re.compile("([_A-Z][_A-Z0-9]*)[ \t]*\((.+)\)", re.UNICODE)\r
 \r
 ## Regular expression for matching macro used in header file inclusion\r
 gMacroPattern = re.compile("([_A-Z][_A-Z0-9]*)[ \t]*\((.+)\)", re.UNICODE)\r
@@ -143,6 +140,11 @@ class BuildFile(object):
         "nmake" :   'if exist %(dir)s $(RD) %(dir)s',\r
         "gmake" :   "$(RD) %(dir)s"\r
     }\r
         "nmake" :   'if exist %(dir)s $(RD) %(dir)s',\r
         "gmake" :   "$(RD) %(dir)s"\r
     }\r
+    ## cp if exist\r
+    _CP_TEMPLATE_ = {\r
+        "nmake" :   'if exist %(Src)s $(CP) %(Src)s %(Dst)s',\r
+        "gmake" :   "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"\r
+    }\r
 \r
     _CD_TEMPLATE_ = {\r
         "nmake" :   'if exist %(dir)s cd %(dir)s',\r
 \r
     _CD_TEMPLATE_ = {\r
         "nmake" :   'if exist %(dir)s cd %(dir)s',\r
@@ -159,7 +161,7 @@ class BuildFile(object):
         "gmake" :   "include"\r
     }\r
 \r
         "gmake" :   "include"\r
     }\r
 \r
-    _INC_FLAG_ = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I", "RVCT" : "-I"}\r
+    _INC_FLAG_ = {TAB_COMPILER_MSFT : "/I", "GCC" : "-I", "INTEL" : "-I", "RVCT" : "-I", "NASM" : "-I"}\r
 \r
     ## Constructor of BuildFile\r
     #\r
 \r
     ## Constructor of BuildFile\r
     #\r
@@ -211,6 +213,8 @@ class BuildFile(object):
             for MacroName in MacroDefinitions:\r
                 MacroValue = MacroDefinitions[MacroName]\r
                 MacroValueLength = len(MacroValue)\r
             for MacroName in MacroDefinitions:\r
                 MacroValue = MacroDefinitions[MacroName]\r
                 MacroValueLength = len(MacroValue)\r
+                if MacroValueLength == 0:\r
+                    continue\r
                 if MacroValueLength <= PathLength and Path.startswith(MacroValue):\r
                     Path = "$(%s)%s" % (MacroName, Path[MacroValueLength:])\r
                     break\r
                 if MacroValueLength <= PathLength and Path.startswith(MacroValue):\r
                     Path = "$(%s)%s" % (MacroName, Path[MacroValueLength:])\r
                     break\r
@@ -233,7 +237,7 @@ PLATFORM_NAME = ${platform_name}
 PLATFORM_GUID = ${platform_guid}\r
 PLATFORM_VERSION = ${platform_version}\r
 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
 PLATFORM_GUID = ${platform_guid}\r
 PLATFORM_VERSION = ${platform_version}\r
 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
-PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
+PLATFORM_DIR = ${platform_dir}\r
 PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
 \r
 #\r
 PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
 \r
 #\r
@@ -241,6 +245,7 @@ PLATFORM_OUTPUT_DIR = ${platform_output_directory}
 #\r
 MODULE_NAME = ${module_name}\r
 MODULE_GUID = ${module_guid}\r
 #\r
 MODULE_NAME = ${module_name}\r
 MODULE_GUID = ${module_guid}\r
+MODULE_NAME_GUID = ${module_name_guid}\r
 MODULE_VERSION = ${module_version}\r
 MODULE_TYPE = ${module_type}\r
 MODULE_FILE = ${module_file}\r
 MODULE_VERSION = ${module_version}\r
 MODULE_TYPE = ${module_type}\r
 MODULE_FILE = ${module_file}\r
@@ -248,7 +253,8 @@ MODULE_FILE_BASE_NAME = ${module_file_base_name}
 BASE_NAME = $(MODULE_NAME)\r
 MODULE_RELATIVE_DIR = ${module_relative_directory}\r
 PACKAGE_RELATIVE_DIR = ${package_relative_directory}\r
 BASE_NAME = $(MODULE_NAME)\r
 MODULE_RELATIVE_DIR = ${module_relative_directory}\r
 PACKAGE_RELATIVE_DIR = ${package_relative_directory}\r
-MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}\r
+MODULE_DIR = ${module_dir}\r
+FFS_OUTPUT_DIR = ${ffs_output_directory}\r
 \r
 MODULE_ENTRY_POINT = ${module_entry_point}\r
 ARCH_ENTRY_POINT = ${arch_entry_point}\r
 \r
 MODULE_ENTRY_POINT = ${module_entry_point}\r
 ARCH_ENTRY_POINT = ${arch_entry_point}\r
@@ -385,7 +391,7 @@ ${END}
 #\r
 clean:\r
 \t${BEGIN}${clean_command}\r
 #\r
 clean:\r
 \t${BEGIN}${clean_command}\r
-\t${END}\r
+\t${END}\t$(RM) AutoGenTimeStamp\r
 \r
 #\r
 # clean all generated files\r
 \r
 #\r
 # clean all generated files\r
@@ -394,6 +400,7 @@ cleanall:
 ${BEGIN}\t${cleanall_command}\r
 ${END}\t$(RM) *.pdb *.idb > NUL 2>&1\r
 \t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi\r
 ${BEGIN}\t${cleanall_command}\r
 ${END}\t$(RM) *.pdb *.idb > NUL 2>&1\r
 \t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi\r
+\t$(RM) AutoGenTimeStamp\r
 \r
 #\r
 # clean all dependent libraries built\r
 \r
 #\r
 # clean all dependent libraries built\r
@@ -416,72 +423,84 @@ cleanlib:
         self.ResultFileList = []\r
         self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]\r
 \r
         self.ResultFileList = []\r
         self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]\r
 \r
-        self.SourceFileDatabase = {}        # {file type : file path}\r
-        self.DestFileDatabase = {}          # {file type : file path}\r
         self.FileBuildTargetList = []       # [(src, target string)]\r
         self.BuildTargetList = []           # [target string]\r
         self.PendingBuildTargetList = []    # [FileBuildRule objects]\r
         self.CommonFileDependency = []\r
         self.FileListMacros = {}\r
         self.ListFileMacros = {}\r
         self.FileBuildTargetList = []       # [(src, target string)]\r
         self.BuildTargetList = []           # [target string]\r
         self.PendingBuildTargetList = []    # [FileBuildRule objects]\r
         self.CommonFileDependency = []\r
         self.FileListMacros = {}\r
         self.ListFileMacros = {}\r
-\r
+        self.ObjTargetDict = OrderedDict()\r
         self.FileCache = {}\r
         self.FileCache = {}\r
-        self.FileDependency = []\r
         self.LibraryBuildCommandList = []\r
         self.LibraryFileList = []\r
         self.LibraryMakefileList = []\r
         self.LibraryBuildDirectoryList = []\r
         self.SystemLibraryList = []\r
         self.LibraryBuildCommandList = []\r
         self.LibraryFileList = []\r
         self.LibraryMakefileList = []\r
         self.LibraryBuildDirectoryList = []\r
         self.SystemLibraryList = []\r
-        self.Macros = sdict()\r
+        self.Macros = OrderedDict()\r
         self.Macros["OUTPUT_DIR"      ] = self._AutoGenObject.Macros["OUTPUT_DIR"]\r
         self.Macros["DEBUG_DIR"       ] = self._AutoGenObject.Macros["DEBUG_DIR"]\r
         self.Macros["MODULE_BUILD_DIR"] = self._AutoGenObject.Macros["MODULE_BUILD_DIR"]\r
         self.Macros["BIN_DIR"         ] = self._AutoGenObject.Macros["BIN_DIR"]\r
         self.Macros["BUILD_DIR"       ] = self._AutoGenObject.Macros["BUILD_DIR"]\r
         self.Macros["WORKSPACE"       ] = self._AutoGenObject.Macros["WORKSPACE"]\r
         self.Macros["OUTPUT_DIR"      ] = self._AutoGenObject.Macros["OUTPUT_DIR"]\r
         self.Macros["DEBUG_DIR"       ] = self._AutoGenObject.Macros["DEBUG_DIR"]\r
         self.Macros["MODULE_BUILD_DIR"] = self._AutoGenObject.Macros["MODULE_BUILD_DIR"]\r
         self.Macros["BIN_DIR"         ] = self._AutoGenObject.Macros["BIN_DIR"]\r
         self.Macros["BUILD_DIR"       ] = self._AutoGenObject.Macros["BUILD_DIR"]\r
         self.Macros["WORKSPACE"       ] = self._AutoGenObject.Macros["WORKSPACE"]\r
+        self.Macros["FFS_OUTPUT_DIR"  ] = self._AutoGenObject.Macros["FFS_OUTPUT_DIR"]\r
+        self.GenFfsList                 = ModuleAutoGen.GenFfsList\r
+        self.MacroList = ['FFS_OUTPUT_DIR', 'MODULE_GUID', 'OUTPUT_DIR']\r
+        self.FfsOutputFileList = []\r
 \r
     # Compose a dict object containing information used to do replacement in template\r
 \r
     # Compose a dict object containing information used to do replacement in template\r
-    def _CreateTemplateDict(self):\r
+    @property\r
+    def _TemplateDict(self):\r
         if self._FileType not in self._SEP_:\r
             EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,\r
                             ExtraData="[%s]" % str(self._AutoGenObject))\r
         if self._FileType not in self._SEP_:\r
             EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,\r
                             ExtraData="[%s]" % str(self._AutoGenObject))\r
+        MyAgo = self._AutoGenObject\r
         Separator = self._SEP_[self._FileType]\r
 \r
         # break build if no source files and binary files are found\r
         Separator = self._SEP_[self._FileType]\r
 \r
         # break build if no source files and binary files are found\r
-        if len(self._AutoGenObject.SourceFileList) == 0 and len(self._AutoGenObject.BinaryFileList) == 0:\r
+        if len(MyAgo.SourceFileList) == 0 and len(MyAgo.BinaryFileList) == 0:\r
             EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"\r
             EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"\r
-                            % (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch),\r
-                            ExtraData="[%s]" % str(self._AutoGenObject))\r
+                            % (MyAgo.BuildTarget, MyAgo.ToolChain, MyAgo.Arch),\r
+                            ExtraData="[%s]" % str(MyAgo))\r
 \r
         # convert dependent libraries to build command\r
         self.ProcessDependentLibrary()\r
 \r
         # convert dependent libraries to build command\r
         self.ProcessDependentLibrary()\r
-        if len(self._AutoGenObject.Module.ModuleEntryPointList) > 0:\r
-            ModuleEntryPoint = self._AutoGenObject.Module.ModuleEntryPointList[0]\r
+        if len(MyAgo.Module.ModuleEntryPointList) > 0:\r
+            ModuleEntryPoint = MyAgo.Module.ModuleEntryPointList[0]\r
         else:\r
             ModuleEntryPoint = "_ModuleEntryPoint"\r
 \r
         else:\r
             ModuleEntryPoint = "_ModuleEntryPoint"\r
 \r
-        # Intel EBC compiler enforces EfiMain\r
-        if self._AutoGenObject.AutoGenVersion < 0x00010005 and self._AutoGenObject.Arch == "EBC":\r
-            ArchEntryPoint = "EfiMain"\r
-        else:\r
-            ArchEntryPoint = ModuleEntryPoint\r
+        ArchEntryPoint = ModuleEntryPoint\r
 \r
 \r
-        if self._AutoGenObject.Arch == "EBC":\r
+        if MyAgo.Arch == "EBC":\r
             # EBC compiler always use "EfiStart" as entry point. Only applies to EdkII modules\r
             ImageEntryPoint = "EfiStart"\r
             # EBC compiler always use "EfiStart" as entry point. Only applies to EdkII modules\r
             ImageEntryPoint = "EfiStart"\r
-        elif self._AutoGenObject.AutoGenVersion < 0x00010005:\r
-            # Edk modules use entry point specified in INF file\r
-            ImageEntryPoint = ModuleEntryPoint\r
         else:\r
             # EdkII modules always use "_ModuleEntryPoint" as entry point\r
             ImageEntryPoint = "_ModuleEntryPoint"\r
 \r
         else:\r
             # EdkII modules always use "_ModuleEntryPoint" as entry point\r
             ImageEntryPoint = "_ModuleEntryPoint"\r
 \r
+        for k, v in MyAgo.Module.Defines.items():\r
+            if k not in MyAgo.Macros:\r
+                MyAgo.Macros[k] = v\r
+\r
+        if 'MODULE_ENTRY_POINT' not in MyAgo.Macros:\r
+            MyAgo.Macros['MODULE_ENTRY_POINT'] = ModuleEntryPoint\r
+        if 'ARCH_ENTRY_POINT' not in MyAgo.Macros:\r
+            MyAgo.Macros['ARCH_ENTRY_POINT'] = ArchEntryPoint\r
+        if 'IMAGE_ENTRY_POINT' not in MyAgo.Macros:\r
+            MyAgo.Macros['IMAGE_ENTRY_POINT'] = ImageEntryPoint\r
+\r
+        PCI_COMPRESS_Flag = False\r
+        for k, v in MyAgo.Module.Defines.items():\r
+            if 'PCI_COMPRESS' == k and 'TRUE' == v:\r
+                PCI_COMPRESS_Flag = True\r
+\r
         # tools definitions\r
         ToolsDef = []\r
         # tools definitions\r
         ToolsDef = []\r
-        IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]\r
-        for Tool in self._AutoGenObject.BuildOption:\r
-            for Attr in self._AutoGenObject.BuildOption[Tool]:\r
-                Value = self._AutoGenObject.BuildOption[Tool][Attr]\r
+        IncPrefix = self._INC_FLAG_[MyAgo.ToolChainFamily]\r
+        for Tool in MyAgo.BuildOption:\r
+            for Attr in MyAgo.BuildOption[Tool]:\r
+                Value = MyAgo.BuildOption[Tool][Attr]\r
                 if Attr == "FAMILY":\r
                     continue\r
                 elif Attr == "PATH":\r
                 if Attr == "FAMILY":\r
                     continue\r
                 elif Attr == "PATH":\r
@@ -492,17 +511,55 @@ cleanlib:
                         continue\r
                     # Remove duplicated include path, if any\r
                     if Attr == "FLAGS":\r
                         continue\r
                     # Remove duplicated include path, if any\r
                     if Attr == "FLAGS":\r
-                        Value = RemoveDupOption(Value, IncPrefix, self._AutoGenObject.IncludePathList)\r
+                        Value = RemoveDupOption(Value, IncPrefix, MyAgo.IncludePathList)\r
+                        if self._AutoGenObject.BuildRuleFamily == TAB_COMPILER_MSFT and Tool == 'CC' and '/GM' in Value:\r
+                            Value = Value.replace(' /MP', '')\r
+                            MyAgo.BuildOption[Tool][Attr] = Value\r
+                        if Tool == "OPTROM" and PCI_COMPRESS_Flag:\r
+                            ValueList = Value.split()\r
+                            if ValueList:\r
+                                for i, v in enumerate(ValueList):\r
+                                    if '-e' == v:\r
+                                        ValueList[i] = '-ec'\r
+                                Value = ' '.join(ValueList)\r
+\r
                     ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value))\r
             ToolsDef.append("")\r
 \r
                     ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value))\r
             ToolsDef.append("")\r
 \r
+        # generate the Response file and Response flag\r
+        RespDict = self.CommandExceedLimit()\r
+        RespFileList = os.path.join(MyAgo.OutputDir, 'respfilelist.txt')\r
+        if RespDict:\r
+            RespFileListContent = ''\r
+            for Resp in RespDict:\r
+                RespFile = os.path.join(MyAgo.OutputDir, str(Resp).lower() + '.txt')\r
+                StrList = RespDict[Resp].split(' ')\r
+                UnexpandMacro = []\r
+                NewStr = []\r
+                for Str in StrList:\r
+                    if '$' in Str:\r
+                        UnexpandMacro.append(Str)\r
+                    else:\r
+                        NewStr.append(Str)\r
+                UnexpandMacroStr = ' '.join(UnexpandMacro)\r
+                NewRespStr = ' '.join(NewStr)\r
+                SaveFileOnChange(RespFile, NewRespStr, False)\r
+                ToolsDef.append("%s = %s" % (Resp, UnexpandMacroStr + ' @' + RespFile))\r
+                RespFileListContent += '@' + RespFile + TAB_LINE_BREAK\r
+                RespFileListContent += NewRespStr + TAB_LINE_BREAK\r
+            SaveFileOnChange(RespFileList, RespFileListContent, False)\r
+        else:\r
+            if os.path.exists(RespFileList):\r
+                os.remove(RespFileList)\r
+\r
         # convert source files and binary files to build targets\r
         # convert source files and binary files to build targets\r
-        self.ResultFileList = [str(T.Target) for T in self._AutoGenObject.CodaTargetList]\r
-        if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:        \r
+        self.ResultFileList = [str(T.Target) for T in MyAgo.CodaTargetList]\r
+        if len(self.ResultFileList) == 0 and len(MyAgo.SourceFileList) != 0:\r
             EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",\r
             EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",\r
-                            ExtraData="[%s]" % str(self._AutoGenObject))\r
+                            ExtraData="[%s]" % str(MyAgo))\r
 \r
         self.ProcessBuildTargetList()\r
 \r
         self.ProcessBuildTargetList()\r
+        self.ParserGenerateFfsCmd()\r
 \r
         # Generate macros used to represent input files\r
         FileMacroList = [] # macro name = file list\r
 \r
         # Generate macros used to represent input files\r
         FileMacroList = [] # macro name = file list\r
@@ -518,10 +575,10 @@ cleanlib:
         # INC_LIST is special\r
         FileMacro = ""\r
         IncludePathList = []\r
         # INC_LIST is special\r
         FileMacro = ""\r
         IncludePathList = []\r
-        for P in  self._AutoGenObject.IncludePathList:\r
-            IncludePathList.append(IncPrefix+self.PlaceMacro(P, self.Macros))\r
+        for P in  MyAgo.IncludePathList:\r
+            IncludePathList.append(IncPrefix + self.PlaceMacro(P, self.Macros))\r
             if FileBuildRule.INC_LIST_MACRO in self.ListFileMacros:\r
             if FileBuildRule.INC_LIST_MACRO in self.ListFileMacros:\r
-                self.ListFileMacros[FileBuildRule.INC_LIST_MACRO].append(IncPrefix+P)\r
+                self.ListFileMacros[FileBuildRule.INC_LIST_MACRO].append(IncPrefix + P)\r
         FileMacro += self._FILE_MACRO_TEMPLATE.Replace(\r
                                                 {\r
                                                     "macro_name"   : "INC",\r
         FileMacro += self._FILE_MACRO_TEMPLATE.Replace(\r
                                                 {\r
                                                     "macro_name"   : "INC",\r
@@ -529,10 +586,28 @@ cleanlib:
                                                 }\r
                                                 )\r
         FileMacroList.append(FileMacro)\r
                                                 }\r
                                                 )\r
         FileMacroList.append(FileMacro)\r
+        # Add support when compiling .nasm source files\r
+        for File in self.FileCache.keys():\r
+            if not str(File).endswith('.nasm'):\r
+                continue\r
+            IncludePathList = []\r
+            for P in  MyAgo.IncludePathList:\r
+                IncludePath = self._INC_FLAG_['NASM'] + self.PlaceMacro(P, self.Macros)\r
+                if IncludePath.endswith(os.sep):\r
+                    IncludePath = IncludePath.rstrip(os.sep)\r
+                # When compiling .nasm files, need to add a literal backslash at each path\r
+                # To specify a literal backslash at the end of the line, precede it with a caret (^)\r
+                if P == MyAgo.IncludePathList[-1] and os.sep == '\\':\r
+                    IncludePath = ''.join([IncludePath, '^', os.sep])\r
+                else:\r
+                    IncludePath = os.path.join(IncludePath, '')\r
+                IncludePathList.append(IncludePath)\r
+            FileMacroList.append(self._FILE_MACRO_TEMPLATE.Replace({"macro_name": "NASM_INC", "source_file": IncludePathList}))\r
+            break\r
 \r
         # Generate macros used to represent files containing list of input files\r
         for ListFileMacro in self.ListFileMacros:\r
 \r
         # Generate macros used to represent files containing list of input files\r
         for ListFileMacro in self.ListFileMacros:\r
-            ListFileName = os.path.join(self._AutoGenObject.OutputDir, "%s.lst" % ListFileMacro.lower()[:len(ListFileMacro)-5])\r
+            ListFileName = os.path.join(MyAgo.OutputDir, "%s.lst" % ListFileMacro.lower()[:len(ListFileMacro) - 5])\r
             FileMacroList.append("%s = %s" % (ListFileMacro, ListFileName))\r
             SaveFileOnChange(\r
                 ListFileName,\r
             FileMacroList.append("%s = %s" % (ListFileMacro, ListFileName))\r
             SaveFileOnChange(\r
                 ListFileName,\r
@@ -540,11 +615,11 @@ cleanlib:
                 False\r
                 )\r
 \r
                 False\r
                 )\r
 \r
-        # Edk modules need <BaseName>StrDefs.h for string ID\r
-        #if self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.UnicodeFileList) > 0:\r
-        #    BcTargetList = ['strdefs']\r
-        #else:\r
-        #    BcTargetList = []\r
+        # Generate objlist used to create .obj file\r
+        for Type in self.ObjTargetDict:\r
+            NewLine = ' '.join(list(self.ObjTargetDict[Type]))\r
+            FileMacroList.append("OBJLIST_%s = %s" % (list(self.ObjTargetDict.keys()).index(Type), NewLine))\r
+\r
         BcTargetList = []\r
 \r
         MakefileName = self._FILE_NAME_[self._FileType]\r
         BcTargetList = []\r
 \r
         MakefileName = self._FILE_NAME_[self._FileType]\r
@@ -553,9 +628,18 @@ cleanlib:
             Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)}\r
             LibraryMakeCommandList.append(Command)\r
 \r
             Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)}\r
             LibraryMakeCommandList.append(Command)\r
 \r
-        package_rel_dir = self._AutoGenObject.SourceDir\r
-        if os.sep in package_rel_dir:\r
-            package_rel_dir = package_rel_dir[package_rel_dir.index(os.sep) + 1:]\r
+        package_rel_dir = MyAgo.SourceDir\r
+        current_dir = self.Macros["WORKSPACE"]\r
+        found = False\r
+        while not found and os.sep in package_rel_dir:\r
+            index = package_rel_dir.index(os.sep)\r
+            current_dir = mws.join(current_dir, package_rel_dir[:index])\r
+            if os.path.exists(current_dir):\r
+                for fl in os.listdir(current_dir):\r
+                    if fl.endswith('.dec'):\r
+                        found = True\r
+                        break\r
+            package_rel_dir = package_rel_dir[index + 1:]\r
 \r
         MakefileTemplateDict = {\r
             "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
 \r
         MakefileTemplateDict = {\r
             "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
@@ -566,31 +650,35 @@ cleanlib:
             "platform_version"          : self.PlatformInfo.Version,\r
             "platform_relative_directory": self.PlatformInfo.SourceDir,\r
             "platform_output_directory" : self.PlatformInfo.OutputDir,\r
             "platform_version"          : self.PlatformInfo.Version,\r
             "platform_relative_directory": self.PlatformInfo.SourceDir,\r
             "platform_output_directory" : self.PlatformInfo.OutputDir,\r
-\r
-            "module_name"               : self._AutoGenObject.Name,\r
-            "module_guid"               : self._AutoGenObject.Guid,\r
-            "module_version"            : self._AutoGenObject.Version,\r
-            "module_type"               : self._AutoGenObject.ModuleType,\r
-            "module_file"               : self._AutoGenObject.MetaFile.Name,\r
-            "module_file_base_name"     : self._AutoGenObject.MetaFile.BaseName,\r
-            "module_relative_directory" : self._AutoGenObject.SourceDir,\r
+            "ffs_output_directory"      : MyAgo.Macros["FFS_OUTPUT_DIR"],\r
+            "platform_dir"              : MyAgo.Macros["PLATFORM_DIR"],\r
+\r
+            "module_name"               : MyAgo.Name,\r
+            "module_guid"               : MyAgo.Guid,\r
+            "module_name_guid"          : MyAgo.UniqueBaseName,\r
+            "module_version"            : MyAgo.Version,\r
+            "module_type"               : MyAgo.ModuleType,\r
+            "module_file"               : MyAgo.MetaFile.Name,\r
+            "module_file_base_name"     : MyAgo.MetaFile.BaseName,\r
+            "module_relative_directory" : MyAgo.SourceDir,\r
+            "module_dir"                : mws.join (self.Macros["WORKSPACE"], MyAgo.SourceDir),\r
             "package_relative_directory": package_rel_dir,\r
             "package_relative_directory": package_rel_dir,\r
-            "module_extra_defines"      : ["%s = %s" % (k, v) for k, v in self._AutoGenObject.Module.Defines.iteritems()],\r
+            "module_extra_defines"      : ["%s = %s" % (k, v) for k, v in MyAgo.Module.Defines.items()],\r
 \r
 \r
-            "architecture"              : self._AutoGenObject.Arch,\r
-            "toolchain_tag"             : self._AutoGenObject.ToolChain,\r
-            "build_target"              : self._AutoGenObject.BuildTarget,\r
+            "architecture"              : MyAgo.Arch,\r
+            "toolchain_tag"             : MyAgo.ToolChain,\r
+            "build_target"              : MyAgo.BuildTarget,\r
 \r
             "platform_build_directory"  : self.PlatformInfo.BuildDir,\r
 \r
             "platform_build_directory"  : self.PlatformInfo.BuildDir,\r
-            "module_build_directory"    : self._AutoGenObject.BuildDir,\r
-            "module_output_directory"   : self._AutoGenObject.OutputDir,\r
-            "module_debug_directory"    : self._AutoGenObject.DebugDir,\r
+            "module_build_directory"    : MyAgo.BuildDir,\r
+            "module_output_directory"   : MyAgo.OutputDir,\r
+            "module_debug_directory"    : MyAgo.DebugDir,\r
 \r
             "separator"                 : Separator,\r
             "module_tool_definitions"   : ToolsDef,\r
 \r
 \r
             "separator"                 : Separator,\r
             "module_tool_definitions"   : ToolsDef,\r
 \r
-            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),\r
-            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),\r
+            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),\r
+            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),\r
 \r
             "module_entry_point"        : ModuleEntryPoint,\r
             "image_entry_point"         : ImageEntryPoint,\r
 \r
             "module_entry_point"        : ModuleEntryPoint,\r
             "image_entry_point"         : ImageEntryPoint,\r
@@ -609,6 +697,190 @@ cleanlib:
 \r
         return MakefileTemplateDict\r
 \r
 \r
         return MakefileTemplateDict\r
 \r
+    def ParserGenerateFfsCmd(self):\r
+        #Add Ffs cmd to self.BuildTargetList\r
+        OutputFile = ''\r
+        DepsFileList = []\r
+\r
+        for Cmd in self.GenFfsList:\r
+            if Cmd[2]:\r
+                for CopyCmd in Cmd[2]:\r
+                    Src, Dst = CopyCmd\r
+                    Src = self.ReplaceMacro(Src)\r
+                    Dst = self.ReplaceMacro(Dst)\r
+                    if Dst not in self.ResultFileList:\r
+                        self.ResultFileList.append(Dst)\r
+                    if '%s :' %(Dst) not in self.BuildTargetList:\r
+                        self.BuildTargetList.append("%s :" %(Dst))\r
+                        self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._FileType] %{'Src': Src, 'Dst': Dst})\r
+\r
+            FfsCmdList = Cmd[0]\r
+            for index, Str in enumerate(FfsCmdList):\r
+                if '-o' == Str:\r
+                    OutputFile = FfsCmdList[index + 1]\r
+                if '-i' == Str or "-oi" == Str:\r
+                    if DepsFileList == []:\r
+                        DepsFileList = [FfsCmdList[index + 1]]\r
+                    else:\r
+                        DepsFileList.append(FfsCmdList[index + 1])\r
+            DepsFileString = ' '.join(DepsFileList).strip()\r
+            if DepsFileString == '':\r
+                continue\r
+            OutputFile = self.ReplaceMacro(OutputFile)\r
+            self.ResultFileList.append(OutputFile)\r
+            DepsFileString = self.ReplaceMacro(DepsFileString)\r
+            self.BuildTargetList.append('%s : %s' % (OutputFile, DepsFileString))\r
+            CmdString = ' '.join(FfsCmdList).strip()\r
+            CmdString = self.ReplaceMacro(CmdString)\r
+            self.BuildTargetList.append('\t%s' % CmdString)\r
+\r
+            self.ParseSecCmd(DepsFileList, Cmd[1])\r
+            for SecOutputFile, SecDepsFile, SecCmd in self.FfsOutputFileList :\r
+                self.BuildTargetList.append('%s : %s' % (self.ReplaceMacro(SecOutputFile), self.ReplaceMacro(SecDepsFile)))\r
+                self.BuildTargetList.append('\t%s' % self.ReplaceMacro(SecCmd))\r
+            self.FfsOutputFileList = []\r
+\r
+    def ParseSecCmd(self, OutputFileList, CmdTuple):\r
+        for OutputFile in OutputFileList:\r
+            for SecCmdStr in CmdTuple:\r
+                SecDepsFileList = []\r
+                SecCmdList = SecCmdStr.split()\r
+                CmdName = SecCmdList[0]\r
+                for index, CmdItem in enumerate(SecCmdList):\r
+                    if '-o' == CmdItem and OutputFile == SecCmdList[index + 1]:\r
+                        index = index + 1\r
+                        while index + 1 < len(SecCmdList):\r
+                            if not SecCmdList[index+1].startswith('-'):\r
+                                SecDepsFileList.append(SecCmdList[index + 1])\r
+                            index = index + 1\r
+                        if CmdName == 'Trim':\r
+                            SecDepsFileList.append(os.path.join('$(DEBUG_DIR)', os.path.basename(OutputFile).replace('offset', 'efi')))\r
+                        if OutputFile.endswith('.ui') or OutputFile.endswith('.ver'):\r
+                            SecDepsFileList.append(os.path.join('$(MODULE_DIR)', '$(MODULE_FILE)'))\r
+                        self.FfsOutputFileList.append((OutputFile, ' '.join(SecDepsFileList), SecCmdStr))\r
+                        if len(SecDepsFileList) > 0:\r
+                            self.ParseSecCmd(SecDepsFileList, CmdTuple)\r
+                        break\r
+                    else:\r
+                        continue\r
+\r
+    def ReplaceMacro(self, str):\r
+        for Macro in self.MacroList:\r
+            if self._AutoGenObject.Macros[Macro] and self._AutoGenObject.Macros[Macro] in str:\r
+                str = str.replace(self._AutoGenObject.Macros[Macro], '$(' + Macro + ')')\r
+        return str\r
+\r
+    def CommandExceedLimit(self):\r
+        FlagDict = {\r
+                    'CC'    :  { 'Macro' : '$(CC_FLAGS)',    'Value' : False},\r
+                    'PP'    :  { 'Macro' : '$(PP_FLAGS)',    'Value' : False},\r
+                    'APP'   :  { 'Macro' : '$(APP_FLAGS)',   'Value' : False},\r
+                    'ASLPP' :  { 'Macro' : '$(ASLPP_FLAGS)', 'Value' : False},\r
+                    'VFRPP' :  { 'Macro' : '$(VFRPP_FLAGS)', 'Value' : False},\r
+                    'ASM'   :  { 'Macro' : '$(ASM_FLAGS)',   'Value' : False},\r
+                    'ASLCC' :  { 'Macro' : '$(ASLCC_FLAGS)', 'Value' : False},\r
+                   }\r
+\r
+        RespDict = {}\r
+        FileTypeList = []\r
+        IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]\r
+\r
+        # base on the source files to decide the file type\r
+        for File in self._AutoGenObject.SourceFileList:\r
+            for type in self._AutoGenObject.FileTypes:\r
+                if File in self._AutoGenObject.FileTypes[type]:\r
+                    if type not in FileTypeList:\r
+                        FileTypeList.append(type)\r
+\r
+        # calculate the command-line length\r
+        if FileTypeList:\r
+            for type in FileTypeList:\r
+                BuildTargets = self._AutoGenObject.BuildRules[type].BuildTargets\r
+                for Target in BuildTargets:\r
+                    CommandList = BuildTargets[Target].Commands\r
+                    for SingleCommand in CommandList:\r
+                        Tool = ''\r
+                        SingleCommandLength = len(SingleCommand)\r
+                        SingleCommandList = SingleCommand.split()\r
+                        if len(SingleCommandList) > 0:\r
+                            for Flag in FlagDict:\r
+                                if '$('+ Flag +')' in SingleCommandList[0]:\r
+                                    Tool = Flag\r
+                                    break\r
+                        if Tool:\r
+                            if 'PATH' not in self._AutoGenObject.BuildOption[Tool]:\r
+                                EdkLogger.error("build", AUTOGEN_ERROR, "%s_PATH doesn't exist in %s ToolChain and %s Arch." %(Tool, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch), ExtraData="[%s]" % str(self._AutoGenObject))\r
+                            SingleCommandLength += len(self._AutoGenObject.BuildOption[Tool]['PATH'])\r
+                            for item in SingleCommandList[1:]:\r
+                                if FlagDict[Tool]['Macro'] in item:\r
+                                    if 'FLAGS' not in self._AutoGenObject.BuildOption[Tool]:\r
+                                        EdkLogger.error("build", AUTOGEN_ERROR, "%s_FLAGS doesn't exist in %s ToolChain and %s Arch." %(Tool, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch), ExtraData="[%s]" % str(self._AutoGenObject))\r
+                                    Str = self._AutoGenObject.BuildOption[Tool]['FLAGS']\r
+                                    for Option in self._AutoGenObject.BuildOption:\r
+                                        for Attr in self._AutoGenObject.BuildOption[Option]:\r
+                                            if Str.find(Option + '_' + Attr) != -1:\r
+                                                Str = Str.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])\r
+                                    while(Str.find('$(') != -1):\r
+                                        for macro in self._AutoGenObject.Macros:\r
+                                            MacroName = '$('+ macro + ')'\r
+                                            if (Str.find(MacroName) != -1):\r
+                                                Str = Str.replace(MacroName, self._AutoGenObject.Macros[macro])\r
+                                                break\r
+                                        else:\r
+                                            break\r
+                                    SingleCommandLength += len(Str)\r
+                                elif '$(INC)' in item:\r
+                                    SingleCommandLength += self._AutoGenObject.IncludePathLength + len(IncPrefix) * len(self._AutoGenObject.IncludePathList)\r
+                                elif item.find('$(') != -1:\r
+                                    Str = item\r
+                                    for Option in self._AutoGenObject.BuildOption:\r
+                                        for Attr in self._AutoGenObject.BuildOption[Option]:\r
+                                            if Str.find(Option + '_' + Attr) != -1:\r
+                                                Str = Str.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])\r
+                                    while(Str.find('$(') != -1):\r
+                                        for macro in self._AutoGenObject.Macros:\r
+                                            MacroName = '$('+ macro + ')'\r
+                                            if (Str.find(MacroName) != -1):\r
+                                                Str = Str.replace(MacroName, self._AutoGenObject.Macros[macro])\r
+                                                break\r
+                                        else:\r
+                                            break\r
+                                    SingleCommandLength += len(Str)\r
+\r
+                            if SingleCommandLength > GlobalData.gCommandMaxLength:\r
+                                FlagDict[Tool]['Value'] = True\r
+\r
+                # generate the response file content by combine the FLAGS and INC\r
+                for Flag in FlagDict:\r
+                    if FlagDict[Flag]['Value']:\r
+                        Key = Flag + '_RESP'\r
+                        RespMacro = FlagDict[Flag]['Macro'].replace('FLAGS', 'RESP')\r
+                        Value = self._AutoGenObject.BuildOption[Flag]['FLAGS']\r
+                        for inc in self._AutoGenObject.IncludePathList:\r
+                            Value += ' ' + IncPrefix + inc\r
+                        for Option in self._AutoGenObject.BuildOption:\r
+                            for Attr in self._AutoGenObject.BuildOption[Option]:\r
+                                if Value.find(Option + '_' + Attr) != -1:\r
+                                    Value = Value.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])\r
+                        while (Value.find('$(') != -1):\r
+                            for macro in self._AutoGenObject.Macros:\r
+                                MacroName = '$('+ macro + ')'\r
+                                if (Value.find(MacroName) != -1):\r
+                                    Value = Value.replace(MacroName, self._AutoGenObject.Macros[macro])\r
+                                    break\r
+                            else:\r
+                                break\r
+\r
+                        if self._AutoGenObject.ToolChainFamily == 'GCC':\r
+                            RespDict[Key] = Value.replace('\\', '/')\r
+                        else:\r
+                            RespDict[Key] = Value\r
+                        for Target in BuildTargets:\r
+                            for i, SingleCommand in enumerate(BuildTargets[Target].Commands):\r
+                                if FlagDict[Flag]['Macro'] in SingleCommand:\r
+                                    BuildTargets[Target].Commands[i] = SingleCommand.replace('$(INC)', '').replace(FlagDict[Flag]['Macro'], RespMacro)\r
+        return RespDict\r
+\r
     def ProcessBuildTargetList(self):\r
         #\r
         # Search dependency file list for each source file\r
     def ProcessBuildTargetList(self):\r
         #\r
         # Search dependency file list for each source file\r
@@ -618,28 +890,38 @@ cleanlib:
             if File.Ext == '.h':\r
                 ForceIncludedFile.append(File)\r
         SourceFileList = []\r
             if File.Ext == '.h':\r
                 ForceIncludedFile.append(File)\r
         SourceFileList = []\r
+        OutPutFileList = []\r
         for Target in self._AutoGenObject.IntroTargetList:\r
             SourceFileList.extend(Target.Inputs)\r
         for Target in self._AutoGenObject.IntroTargetList:\r
             SourceFileList.extend(Target.Inputs)\r
+            OutPutFileList.extend(Target.Outputs)\r
 \r
 \r
-        self.FileDependency = self.GetFileDependency(\r
+        if OutPutFileList:\r
+            for Item in OutPutFileList:\r
+                if Item in SourceFileList:\r
+                    SourceFileList.remove(Item)\r
+\r
+        FileDependencyDict = self.GetFileDependency(\r
                                     SourceFileList,\r
                                     ForceIncludedFile,\r
                                     self._AutoGenObject.IncludePathList + self._AutoGenObject.BuildOptionIncPathList\r
                                     )\r
         DepSet = None\r
                                     SourceFileList,\r
                                     ForceIncludedFile,\r
                                     self._AutoGenObject.IncludePathList + self._AutoGenObject.BuildOptionIncPathList\r
                                     )\r
         DepSet = None\r
-        for File in self.FileDependency:\r
-            if not self.FileDependency[File]:\r
-                self.FileDependency[File] = ['$(FORCE_REBUILD)']\r
+        for File,Dependency in FileDependencyDict.items():\r
+            if not Dependency:\r
+                FileDependencyDict[File] = ['$(FORCE_REBUILD)']\r
                 continue\r
                 continue\r
+\r
+            self._AutoGenObject.AutoGenDepSet |= set(Dependency)\r
+\r
             # skip non-C files\r
             if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":\r
                 continue\r
             # skip non-C files\r
             if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":\r
                 continue\r
-            elif DepSet == None:\r
-                DepSet = set(self.FileDependency[File])\r
+            elif DepSet is None:\r
+                DepSet = set(Dependency)\r
             else:\r
             else:\r
-                DepSet &= set(self.FileDependency[File])\r
+                DepSet &= set(Dependency)\r
         # in case nothing in SourceFileList\r
         # in case nothing in SourceFileList\r
-        if DepSet == None:\r
+        if DepSet is None:\r
             DepSet = set()\r
         #\r
         # Extract common files list in the dependency files\r
             DepSet = set()\r
         #\r
         # Extract common files list in the dependency files\r
@@ -647,15 +929,26 @@ cleanlib:
         for File in DepSet:\r
             self.CommonFileDependency.append(self.PlaceMacro(File.Path, self.Macros))\r
 \r
         for File in DepSet:\r
             self.CommonFileDependency.append(self.PlaceMacro(File.Path, self.Macros))\r
 \r
-        for File in self.FileDependency:\r
+        CmdSumDict = {}\r
+        CmdTargetDict = {}\r
+        CmdCppDict = {}\r
+        DependencyDict = FileDependencyDict.copy()\r
+        for File in FileDependencyDict:\r
             # skip non-C files\r
             if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":\r
                 continue\r
             # skip non-C files\r
             if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":\r
                 continue\r
-            NewDepSet = set(self.FileDependency[File])\r
+            NewDepSet = set(FileDependencyDict[File])\r
             NewDepSet -= DepSet\r
             NewDepSet -= DepSet\r
-            self.FileDependency[File] = ["$(COMMON_DEPS)"] + list(NewDepSet)\r
+            FileDependencyDict[File] = ["$(COMMON_DEPS)"] + list(NewDepSet)\r
+            DependencyDict[File] = list(NewDepSet)\r
 \r
         # Convert target description object to target string in makefile\r
 \r
         # Convert target description object to target string in makefile\r
+        if self._AutoGenObject.BuildRuleFamily == TAB_COMPILER_MSFT and TAB_C_CODE_FILE in self._AutoGenObject.Targets:\r
+            for T in self._AutoGenObject.Targets[TAB_C_CODE_FILE]:\r
+                NewFile = self.PlaceMacro(str(T), self.Macros)\r
+                if not self.ObjTargetDict.get(T.Target.SubDir):\r
+                    self.ObjTargetDict[T.Target.SubDir] = set()\r
+                self.ObjTargetDict[T.Target.SubDir].add(NewFile)\r
         for Type in self._AutoGenObject.Targets:\r
             for T in self._AutoGenObject.Targets[Type]:\r
                 # Generate related macros if needed\r
         for Type in self._AutoGenObject.Targets:\r
             for T in self._AutoGenObject.Targets[Type]:\r
                 # Generate related macros if needed\r
@@ -667,19 +960,22 @@ cleanlib:
                     self.ListFileMacros[T.IncListFileMacro] = []\r
 \r
                 Deps = []\r
                     self.ListFileMacros[T.IncListFileMacro] = []\r
 \r
                 Deps = []\r
+                CCodeDeps = []\r
                 # Add force-dependencies\r
                 for Dep in T.Dependencies:\r
                     Deps.append(self.PlaceMacro(str(Dep), self.Macros))\r
                 # Add force-dependencies\r
                 for Dep in T.Dependencies:\r
                     Deps.append(self.PlaceMacro(str(Dep), self.Macros))\r
+                    if Dep != '$(MAKE_FILE)':\r
+                        CCodeDeps.append(self.PlaceMacro(str(Dep), self.Macros))\r
                 # Add inclusion-dependencies\r
                 # Add inclusion-dependencies\r
-                if len(T.Inputs) == 1 and T.Inputs[0] in self.FileDependency:\r
-                    for F in self.FileDependency[T.Inputs[0]]:\r
+                if len(T.Inputs) == 1 and T.Inputs[0] in FileDependencyDict:\r
+                    for F in FileDependencyDict[T.Inputs[0]]:\r
                         Deps.append(self.PlaceMacro(str(F), self.Macros))\r
                 # Add source-dependencies\r
                 for F in T.Inputs:\r
                     NewFile = self.PlaceMacro(str(F), self.Macros)\r
                     # In order to use file list macro as dependency\r
                     if T.GenListFile:\r
                         Deps.append(self.PlaceMacro(str(F), self.Macros))\r
                 # Add source-dependencies\r
                 for F in T.Inputs:\r
                     NewFile = self.PlaceMacro(str(F), self.Macros)\r
                     # In order to use file list macro as dependency\r
                     if T.GenListFile:\r
-                        # gnu tools need forward slash path separater, even on Windows\r
+                        # gnu tools need forward slash path separator, even on Windows\r
                         self.ListFileMacros[T.ListFileMacro].append(str(F).replace ('\\', '/'))\r
                         self.FileListMacros[T.FileListMacro].append(NewFile)\r
                     elif T.GenFileListMacro:\r
                         self.ListFileMacros[T.ListFileMacro].append(str(F).replace ('\\', '/'))\r
                         self.FileListMacros[T.FileListMacro].append(NewFile)\r
                     elif T.GenFileListMacro:\r
@@ -690,18 +986,68 @@ cleanlib:
                 # Use file list macro as dependency\r
                 if T.GenFileListMacro:\r
                     Deps.append("$(%s)" % T.FileListMacro)\r
                 # Use file list macro as dependency\r
                 if T.GenFileListMacro:\r
                     Deps.append("$(%s)" % T.FileListMacro)\r
-\r
-                TargetDict = {\r
-                    "target"    :   self.PlaceMacro(T.Target.Path, self.Macros),\r
-                    "cmd"       :   "\n\t".join(T.Commands),\r
-                    "deps"      :   Deps\r
-                }\r
-                self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(TargetDict))\r
+                    if Type in [TAB_OBJECT_FILE, TAB_STATIC_LIBRARY]:\r
+                        Deps.append("$(%s)" % T.ListFileMacro)\r
+\r
+                if self._AutoGenObject.BuildRuleFamily == TAB_COMPILER_MSFT and Type == TAB_C_CODE_FILE:\r
+                    T, CmdTarget, CmdTargetDict, CmdCppDict = self.ParserCCodeFile(T, Type, CmdSumDict, CmdTargetDict, CmdCppDict, DependencyDict)\r
+                    TargetDict = {"target": self.PlaceMacro(T.Target.Path, self.Macros), "cmd": "\n\t".join(T.Commands),"deps": CCodeDeps}\r
+                    CmdLine = self._BUILD_TARGET_TEMPLATE.Replace(TargetDict).rstrip().replace('\t$(OBJLIST', '$(OBJLIST')\r
+                    if T.Commands:\r
+                        CmdLine = '%s%s' %(CmdLine, TAB_LINE_BREAK)\r
+                    if CCodeDeps or CmdLine:\r
+                        self.BuildTargetList.append(CmdLine)\r
+                else:\r
+                    TargetDict = {"target": self.PlaceMacro(T.Target.Path, self.Macros), "cmd": "\n\t".join(T.Commands),"deps": Deps}\r
+                    self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(TargetDict))\r
+\r
+    def ParserCCodeFile(self, T, Type, CmdSumDict, CmdTargetDict, CmdCppDict, DependencyDict):\r
+        if not CmdSumDict:\r
+            for item in self._AutoGenObject.Targets[Type]:\r
+                CmdSumDict[item.Target.SubDir] = item.Target.BaseName\r
+                for CppPath in item.Inputs:\r
+                    Path = self.PlaceMacro(CppPath.Path, self.Macros)\r
+                    if CmdCppDict.get(item.Target.SubDir):\r
+                        CmdCppDict[item.Target.SubDir].append(Path)\r
+                    else:\r
+                        CmdCppDict[item.Target.SubDir] = ['$(MAKE_FILE)', Path]\r
+                    if CppPath.Path in DependencyDict:\r
+                        for Temp in DependencyDict[CppPath.Path]:\r
+                            try:\r
+                                Path = self.PlaceMacro(Temp.Path, self.Macros)\r
+                            except:\r
+                                continue\r
+                            if Path not in (self.CommonFileDependency + CmdCppDict[item.Target.SubDir]):\r
+                                CmdCppDict[item.Target.SubDir].append(Path)\r
+        if T.Commands:\r
+            CommandList = T.Commands[:]\r
+            for Item in CommandList[:]:\r
+                SingleCommandList = Item.split()\r
+                if len(SingleCommandList) > 0 and '$(CC)' in SingleCommandList[0]:\r
+                    for Temp in SingleCommandList:\r
+                        if Temp.startswith('/Fo'):\r
+                            CmdSign = '%s%s' % (Temp.rsplit(TAB_SLASH, 1)[0], TAB_SLASH)\r
+                            break\r
+                    else: continue\r
+                    if CmdSign not in list(CmdTargetDict.keys()):\r
+                        CmdTargetDict[CmdSign] = Item.replace(Temp, CmdSign)\r
+                    else:\r
+                        CmdTargetDict[CmdSign] = "%s %s" % (CmdTargetDict[CmdSign], SingleCommandList[-1])\r
+                    Index = CommandList.index(Item)\r
+                    CommandList.pop(Index)\r
+                    if SingleCommandList[-1].endswith("%s%s.c" % (TAB_SLASH, CmdSumDict[CmdSign.lstrip('/Fo').rsplit(TAB_SLASH, 1)[0]])):\r
+                        Cpplist = CmdCppDict[T.Target.SubDir]\r
+                        Cpplist.insert(0, '$(OBJLIST_%d): $(COMMON_DEPS)' % list(self.ObjTargetDict.keys()).index(T.Target.SubDir))\r
+                        T.Commands[Index] = '%s\n\t%s' % (' \\\n\t'.join(Cpplist), CmdTargetDict[CmdSign])\r
+                    else:\r
+                        T.Commands.pop(Index)\r
+        return T, CmdSumDict, CmdTargetDict, CmdCppDict\r
 \r
     ## For creating makefile targets for dependent libraries\r
     def ProcessDependentLibrary(self):\r
         for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
 \r
     ## For creating makefile targets for dependent libraries\r
     def ProcessDependentLibrary(self):\r
         for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
-            self.LibraryBuildDirectoryList.append(self.PlaceMacro(LibraryAutoGen.BuildDir, self.Macros))\r
+            if not LibraryAutoGen.IsBinaryModule and not LibraryAutoGen.CanSkipbyHash():\r
+                self.LibraryBuildDirectoryList.append(self.PlaceMacro(LibraryAutoGen.BuildDir, self.Macros))\r
 \r
     ## Return a list containing source file's dependencies\r
     #\r
 \r
     ## Return a list containing source file's dependencies\r
     #\r
@@ -720,7 +1066,7 @@ cleanlib:
     ## Find dependencies for one source file\r
     #\r
     #  By searching recursively "#include" directive in file, find out all the\r
     ## Find dependencies for one source file\r
     #\r
     #  By searching recursively "#include" directive in file, find out all the\r
-    #  files needed by given source file. The dependecies will be only searched\r
+    #  files needed by given source file. The dependencies will be only searched\r
     #  in given search path list.\r
     #\r
     #   @param      File            The source file\r
     #  in given search path list.\r
     #\r
     #   @param      File            The source file\r
@@ -755,17 +1101,21 @@ cleanlib:
                 CurrentFileDependencyList = DepDb[F]\r
             else:\r
                 try:\r
                 CurrentFileDependencyList = DepDb[F]\r
             else:\r
                 try:\r
-                    Fd = open(F.Path, 'r')\r
-                except BaseException, X:\r
-                    EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F.Path+"\n\t"+str(X))\r
-\r
-                FileContent = Fd.read()\r
-                Fd.close()\r
+                    Fd = open(F.Path, 'rb')\r
+                    FileContent = Fd.read()\r
+                    Fd.close()\r
+                except BaseException as X:\r
+                    EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F.Path + "\n\t" + str(X))\r
                 if len(FileContent) == 0:\r
                     continue\r
                 if len(FileContent) == 0:\r
                     continue\r
-\r
-                if FileContent[0] == 0xff or FileContent[0] == 0xfe:\r
-                    FileContent = unicode(FileContent, "utf-16")\r
+                try:\r
+                    if FileContent[0] == 0xff or FileContent[0] == 0xfe:\r
+                        FileContent = FileContent.decode('utf-16')\r
+                    else:\r
+                        FileContent = FileContent.decode()\r
+                except:\r
+                    # The file is not txt file. for example .mcb file\r
+                    continue\r
                 IncludedFileList = gIncludePattern.findall(FileContent)\r
 \r
                 for Inc in IncludedFileList:\r
                 IncludedFileList = gIncludePattern.findall(FileContent)\r
 \r
                 for Inc in IncludedFileList:\r
@@ -819,8 +1169,6 @@ cleanlib:
 \r
         return DependencyList\r
 \r
 \r
         return DependencyList\r
 \r
-    _TemplateDict = property(_CreateTemplateDict)\r
-\r
 ## CustomMakefile class\r
 #\r
 #  This class encapsules makefie and its generation for module. It uses template to generate\r
 ## CustomMakefile class\r
 #\r
 #  This class encapsules makefie and its generation for module. It uses template to generate\r
@@ -838,7 +1186,7 @@ PLATFORM_NAME = ${platform_name}
 PLATFORM_GUID = ${platform_guid}\r
 PLATFORM_VERSION = ${platform_version}\r
 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
 PLATFORM_GUID = ${platform_guid}\r
 PLATFORM_VERSION = ${platform_version}\r
 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
-PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
+PLATFORM_DIR = ${platform_dir}\r
 PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
 \r
 #\r
 PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
 \r
 #\r
@@ -846,13 +1194,14 @@ PLATFORM_OUTPUT_DIR = ${platform_output_directory}
 #\r
 MODULE_NAME = ${module_name}\r
 MODULE_GUID = ${module_guid}\r
 #\r
 MODULE_NAME = ${module_name}\r
 MODULE_GUID = ${module_guid}\r
+MODULE_NAME_GUID = ${module_name_guid}\r
 MODULE_VERSION = ${module_version}\r
 MODULE_TYPE = ${module_type}\r
 MODULE_FILE = ${module_file}\r
 MODULE_FILE_BASE_NAME = ${module_file_base_name}\r
 BASE_NAME = $(MODULE_NAME)\r
 MODULE_RELATIVE_DIR = ${module_relative_directory}\r
 MODULE_VERSION = ${module_version}\r
 MODULE_TYPE = ${module_type}\r
 MODULE_FILE = ${module_file}\r
 MODULE_FILE_BASE_NAME = ${module_file_base_name}\r
 BASE_NAME = $(MODULE_NAME)\r
 MODULE_RELATIVE_DIR = ${module_relative_directory}\r
-MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}\r
+MODULE_DIR = ${module_dir}\r
 \r
 #\r
 # Build Configuration Macro Definition\r
 \r
 #\r
 # Build Configuration Macro Definition\r
@@ -928,34 +1277,36 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
         self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]\r
 \r
     # Compose a dict object containing information used to do replacement in template\r
         self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]\r
 \r
     # Compose a dict object containing information used to do replacement in template\r
-    def _CreateTemplateDict(self):\r
+    @property\r
+    def _TemplateDict(self):\r
         Separator = self._SEP_[self._FileType]\r
         Separator = self._SEP_[self._FileType]\r
-        if self._FileType not in self._AutoGenObject.CustomMakefile:\r
+        MyAgo = self._AutoGenObject\r
+        if self._FileType not in MyAgo.CustomMakefile:\r
             EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,\r
             EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,\r
-                            ExtraData="[%s]" % str(self._AutoGenObject))\r
-        MakefilePath = os.path.join(\r
-                                self._AutoGenObject.WorkspaceDir,\r
-                                self._AutoGenObject.CustomMakefile[self._FileType]\r
+                            ExtraData="[%s]" % str(MyAgo))\r
+        MakefilePath = mws.join(\r
+                                MyAgo.WorkspaceDir,\r
+                                MyAgo.CustomMakefile[self._FileType]\r
                                 )\r
         try:\r
             CustomMakefile = open(MakefilePath, 'r').read()\r
         except:\r
                                 )\r
         try:\r
             CustomMakefile = open(MakefilePath, 'r').read()\r
         except:\r
-            EdkLogger.error('build', FILE_OPEN_FAILURE, File=str(self._AutoGenObject),\r
-                            ExtraData=self._AutoGenObject.CustomMakefile[self._FileType])\r
+            EdkLogger.error('build', FILE_OPEN_FAILURE, File=str(MyAgo),\r
+                            ExtraData=MyAgo.CustomMakefile[self._FileType])\r
 \r
         # tools definitions\r
         ToolsDef = []\r
 \r
         # tools definitions\r
         ToolsDef = []\r
-        for Tool in self._AutoGenObject.BuildOption:\r
+        for Tool in MyAgo.BuildOption:\r
             # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.\r
             if Tool == "MAKE":\r
                 continue\r
             # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.\r
             if Tool == "MAKE":\r
                 continue\r
-            for Attr in self._AutoGenObject.BuildOption[Tool]:\r
+            for Attr in MyAgo.BuildOption[Tool]:\r
                 if Attr == "FAMILY":\r
                     continue\r
                 elif Attr == "PATH":\r
                 if Attr == "FAMILY":\r
                     continue\r
                 elif Attr == "PATH":\r
-                    ToolsDef.append("%s = %s" % (Tool, self._AutoGenObject.BuildOption[Tool][Attr]))\r
+                    ToolsDef.append("%s = %s" % (Tool, MyAgo.BuildOption[Tool][Attr]))\r
                 else:\r
                 else:\r
-                    ToolsDef.append("%s_%s = %s" % (Tool, Attr, self._AutoGenObject.BuildOption[Tool][Attr]))\r
+                    ToolsDef.append("%s_%s = %s" % (Tool, Attr, MyAgo.BuildOption[Tool][Attr]))\r
             ToolsDef.append("")\r
 \r
         MakefileName = self._FILE_NAME_[self._FileType]\r
             ToolsDef.append("")\r
 \r
         MakefileName = self._FILE_NAME_[self._FileType]\r
@@ -967,29 +1318,32 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
             "platform_version"          : self.PlatformInfo.Version,\r
             "platform_relative_directory": self.PlatformInfo.SourceDir,\r
             "platform_output_directory" : self.PlatformInfo.OutputDir,\r
             "platform_version"          : self.PlatformInfo.Version,\r
             "platform_relative_directory": self.PlatformInfo.SourceDir,\r
             "platform_output_directory" : self.PlatformInfo.OutputDir,\r
-\r
-            "module_name"               : self._AutoGenObject.Name,\r
-            "module_guid"               : self._AutoGenObject.Guid,\r
-            "module_version"            : self._AutoGenObject.Version,\r
-            "module_type"               : self._AutoGenObject.ModuleType,\r
-            "module_file"               : self._AutoGenObject.MetaFile,\r
-            "module_file_base_name"     : self._AutoGenObject.MetaFile.BaseName,\r
-            "module_relative_directory" : self._AutoGenObject.SourceDir,\r
-\r
-            "architecture"              : self._AutoGenObject.Arch,\r
-            "toolchain_tag"             : self._AutoGenObject.ToolChain,\r
-            "build_target"              : self._AutoGenObject.BuildTarget,\r
+            "platform_dir"              : MyAgo.Macros["PLATFORM_DIR"],\r
+\r
+            "module_name"               : MyAgo.Name,\r
+            "module_guid"               : MyAgo.Guid,\r
+            "module_name_guid"          : MyAgo.UniqueBaseName,\r
+            "module_version"            : MyAgo.Version,\r
+            "module_type"               : MyAgo.ModuleType,\r
+            "module_file"               : MyAgo.MetaFile,\r
+            "module_file_base_name"     : MyAgo.MetaFile.BaseName,\r
+            "module_relative_directory" : MyAgo.SourceDir,\r
+            "module_dir"                : mws.join (MyAgo.WorkspaceDir, MyAgo.SourceDir),\r
+\r
+            "architecture"              : MyAgo.Arch,\r
+            "toolchain_tag"             : MyAgo.ToolChain,\r
+            "build_target"              : MyAgo.BuildTarget,\r
 \r
             "platform_build_directory"  : self.PlatformInfo.BuildDir,\r
 \r
             "platform_build_directory"  : self.PlatformInfo.BuildDir,\r
-            "module_build_directory"    : self._AutoGenObject.BuildDir,\r
-            "module_output_directory"   : self._AutoGenObject.OutputDir,\r
-            "module_debug_directory"    : self._AutoGenObject.DebugDir,\r
+            "module_build_directory"    : MyAgo.BuildDir,\r
+            "module_output_directory"   : MyAgo.OutputDir,\r
+            "module_debug_directory"    : MyAgo.DebugDir,\r
 \r
             "separator"                 : Separator,\r
             "module_tool_definitions"   : ToolsDef,\r
 \r
 \r
             "separator"                 : Separator,\r
             "module_tool_definitions"   : ToolsDef,\r
 \r
-            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),\r
-            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),\r
+            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),\r
+            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),\r
 \r
             "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
             "custom_makefile_content"   : CustomMakefile\r
 \r
             "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
             "custom_makefile_content"   : CustomMakefile\r
@@ -997,8 +1351,6 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
 \r
         return MakefileTemplateDict\r
 \r
 \r
         return MakefileTemplateDict\r
 \r
-    _TemplateDict = property(_CreateTemplateDict)\r
-\r
 ## PlatformMakefile class\r
 #\r
 #  This class encapsules makefie and its generation for platform. It uses\r
 ## PlatformMakefile class\r
 #\r
 #  This class encapsules makefie and its generation for platform. It uses\r
@@ -1017,7 +1369,7 @@ PLATFORM_NAME = ${platform_name}
 PLATFORM_GUID = ${platform_guid}\r
 PLATFORM_VERSION = ${platform_version}\r
 PLATFORM_FILE = ${platform_file}\r
 PLATFORM_GUID = ${platform_guid}\r
 PLATFORM_VERSION = ${platform_version}\r
 PLATFORM_FILE = ${platform_file}\r
-PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
+PLATFORM_DIR = ${platform_dir}\r
 PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
 \r
 #\r
 PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
 \r
 #\r
@@ -1115,13 +1467,14 @@ cleanlib:
         self.LibraryMakeCommandList = []\r
 \r
     # Compose a dict object containing information used to do replacement in template\r
         self.LibraryMakeCommandList = []\r
 \r
     # Compose a dict object containing information used to do replacement in template\r
-    def _CreateTemplateDict(self):\r
+    @property\r
+    def _TemplateDict(self):\r
         Separator = self._SEP_[self._FileType]\r
 \r
         Separator = self._SEP_[self._FileType]\r
 \r
-        PlatformInfo = self._AutoGenObject\r
-        if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]:\r
+        MyAgo = self._AutoGenObject\r
+        if "MAKE" not in MyAgo.ToolDefinition or "PATH" not in MyAgo.ToolDefinition["MAKE"]:\r
             EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",\r
             EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",\r
-                            ExtraData="[%s]" % str(self._AutoGenObject))\r
+                            ExtraData="[%s]" % str(MyAgo))\r
 \r
         self.IntermediateDirectoryList = ["$(BUILD_DIR)"]\r
         self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()\r
 \r
         self.IntermediateDirectoryList = ["$(BUILD_DIR)"]\r
         self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()\r
@@ -1131,7 +1484,7 @@ cleanlib:
         LibraryMakefileList = []\r
         LibraryMakeCommandList = []\r
         for D in self.LibraryBuildDirectoryList:\r
         LibraryMakefileList = []\r
         LibraryMakeCommandList = []\r
         for D in self.LibraryBuildDirectoryList:\r
-            D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.BuildDir})\r
+            D = self.PlaceMacro(D, {"BUILD_DIR":MyAgo.BuildDir})\r
             Makefile = os.path.join(D, MakefileName)\r
             Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}\r
             LibraryMakefileList.append(Makefile)\r
             Makefile = os.path.join(D, MakefileName)\r
             Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}\r
             LibraryMakefileList.append(Makefile)\r
@@ -1141,7 +1494,7 @@ cleanlib:
         ModuleMakefileList = []\r
         ModuleMakeCommandList = []\r
         for D in self.ModuleBuildDirectoryList:\r
         ModuleMakefileList = []\r
         ModuleMakeCommandList = []\r
         for D in self.ModuleBuildDirectoryList:\r
-            D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.BuildDir})\r
+            D = self.PlaceMacro(D, {"BUILD_DIR":MyAgo.BuildDir})\r
             Makefile = os.path.join(D, MakefileName)\r
             Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}\r
             ModuleMakefileList.append(Makefile)\r
             Makefile = os.path.join(D, MakefileName)\r
             Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}\r
             ModuleMakefileList.append(Makefile)\r
@@ -1150,22 +1503,23 @@ cleanlib:
         MakefileTemplateDict = {\r
             "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
             "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),\r
         MakefileTemplateDict = {\r
             "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
             "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),\r
-            "make_path"                 : PlatformInfo.ToolDefinition["MAKE"]["PATH"],\r
+            "make_path"                 : MyAgo.ToolDefinition["MAKE"]["PATH"],\r
             "makefile_name"             : MakefileName,\r
             "makefile_name"             : MakefileName,\r
-            "platform_name"             : PlatformInfo.Name,\r
-            "platform_guid"             : PlatformInfo.Guid,\r
-            "platform_version"          : PlatformInfo.Version,\r
-            "platform_file"             : self._AutoGenObject.MetaFile,\r
-            "platform_relative_directory": PlatformInfo.SourceDir,\r
-            "platform_output_directory" : PlatformInfo.OutputDir,\r
-            "platform_build_directory"  : PlatformInfo.BuildDir,\r
-\r
-            "toolchain_tag"             : PlatformInfo.ToolChain,\r
-            "build_target"              : PlatformInfo.BuildTarget,\r
-            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),\r
-            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),\r
-            "build_architecture_list"   : self._AutoGenObject.Arch,\r
-            "architecture"              : self._AutoGenObject.Arch,\r
+            "platform_name"             : MyAgo.Name,\r
+            "platform_guid"             : MyAgo.Guid,\r
+            "platform_version"          : MyAgo.Version,\r
+            "platform_file"             : MyAgo.MetaFile,\r
+            "platform_relative_directory": MyAgo.SourceDir,\r
+            "platform_output_directory" : MyAgo.OutputDir,\r
+            "platform_build_directory"  : MyAgo.BuildDir,\r
+            "platform_dir"              : MyAgo.Macros["PLATFORM_DIR"],\r
+\r
+            "toolchain_tag"             : MyAgo.ToolChain,\r
+            "build_target"              : MyAgo.BuildTarget,\r
+            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),\r
+            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),\r
+            "build_architecture_list"   : MyAgo.Arch,\r
+            "architecture"              : MyAgo.Arch,\r
             "separator"                 : Separator,\r
             "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
             "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),\r
             "separator"                 : Separator,\r
             "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
             "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),\r
@@ -1195,12 +1549,10 @@ cleanlib:
     def GetLibraryBuildDirectoryList(self):\r
         DirList = []\r
         for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
     def GetLibraryBuildDirectoryList(self):\r
         DirList = []\r
         for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
-            if not LibraryAutoGen.IsBinaryModule:\r
+            if not LibraryAutoGen.IsBinaryModule and not LibraryAutoGen.CanSkipbyHash():\r
                 DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))\r
         return DirList\r
 \r
                 DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))\r
         return DirList\r
 \r
-    _TemplateDict = property(_CreateTemplateDict)\r
-\r
 ## TopLevelMakefile class\r
 #\r
 #  This class encapsules makefie and its generation for entrance makefile. It\r
 ## TopLevelMakefile class\r
 #\r
 #  This class encapsules makefie and its generation for entrance makefile. It\r
@@ -1220,32 +1572,29 @@ class TopLevelMakefile(BuildFile):
         self.IntermediateDirectoryList = []\r
 \r
     # Compose a dict object containing information used to do replacement in template\r
         self.IntermediateDirectoryList = []\r
 \r
     # Compose a dict object containing information used to do replacement in template\r
-    def _CreateTemplateDict(self):\r
+    @property\r
+    def _TemplateDict(self):\r
         Separator = self._SEP_[self._FileType]\r
 \r
         # any platform autogen object is ok because we just need common information\r
         Separator = self._SEP_[self._FileType]\r
 \r
         # any platform autogen object is ok because we just need common information\r
-        PlatformInfo = self._AutoGenObject\r
+        MyAgo = self._AutoGenObject\r
 \r
 \r
-        if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]:\r
+        if "MAKE" not in MyAgo.ToolDefinition or "PATH" not in MyAgo.ToolDefinition["MAKE"]:\r
             EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",\r
             EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",\r
-                            ExtraData="[%s]" % str(self._AutoGenObject))\r
+                            ExtraData="[%s]" % str(MyAgo))\r
 \r
 \r
-        for Arch in PlatformInfo.ArchList:\r
+        for Arch in MyAgo.ArchList:\r
             self.IntermediateDirectoryList.append(Separator.join(["$(BUILD_DIR)", Arch]))\r
         self.IntermediateDirectoryList.append("$(FV_DIR)")\r
 \r
         # TRICK: for not generating GenFds call in makefile if no FDF file\r
         MacroList = []\r
             self.IntermediateDirectoryList.append(Separator.join(["$(BUILD_DIR)", Arch]))\r
         self.IntermediateDirectoryList.append("$(FV_DIR)")\r
 \r
         # TRICK: for not generating GenFds call in makefile if no FDF file\r
         MacroList = []\r
-        if PlatformInfo.FdfFile != None and PlatformInfo.FdfFile != "":\r
-            FdfFileList = [PlatformInfo.FdfFile]\r
+        if MyAgo.FdfFile is not None and MyAgo.FdfFile != "":\r
+            FdfFileList = [MyAgo.FdfFile]\r
             # macros passed to GenFds\r
             # macros passed to GenFds\r
-            MacroList.append('"%s=%s"' % ("EFI_SOURCE", GlobalData.gEfiSource.replace('\\', '\\\\')))\r
-            MacroList.append('"%s=%s"' % ("EDK_SOURCE", GlobalData.gEdkSource.replace('\\', '\\\\')))\r
             MacroDict = {}\r
             MacroDict.update(GlobalData.gGlobalDefines)\r
             MacroDict.update(GlobalData.gCommandLineDefines)\r
             MacroDict = {}\r
             MacroDict.update(GlobalData.gGlobalDefines)\r
             MacroDict.update(GlobalData.gCommandLineDefines)\r
-            MacroDict.pop("EFI_SOURCE", "dummy")\r
-            MacroDict.pop("EDK_SOURCE", "dummy")\r
             for MacroName in MacroDict:\r
                 if MacroDict[MacroName] != "":\r
                     MacroList.append('"%s=%s"' % (MacroName, MacroDict[MacroName].replace('\\', '\\\\')))\r
             for MacroName in MacroDict:\r
                 if MacroDict[MacroName] != "":\r
                     MacroList.append('"%s=%s"' % (MacroName, MacroDict[MacroName].replace('\\', '\\\\')))\r
@@ -1266,41 +1615,52 @@ class TopLevelMakefile(BuildFile):
 \r
         if GlobalData.gCaseInsensitive:\r
             ExtraOption += " -c"\r
 \r
         if GlobalData.gCaseInsensitive:\r
             ExtraOption += " -c"\r
-\r
+        if GlobalData.gEnableGenfdsMultiThread:\r
+            ExtraOption += " --genfds-multi-thread"\r
         if GlobalData.gIgnoreSource:\r
             ExtraOption += " --ignore-sources"\r
 \r
         if GlobalData.gIgnoreSource:\r
             ExtraOption += " --ignore-sources"\r
 \r
+        for pcd in GlobalData.BuildOptionPcd:\r
+            if pcd[2]:\r
+                pcdname = '.'.join(pcd[0:3])\r
+            else:\r
+                pcdname = '.'.join(pcd[0:2])\r
+            if pcd[3].startswith('{'):\r
+                ExtraOption += " --pcd " + pcdname + '=' + 'H' + '"' + pcd[3] + '"'\r
+            else:\r
+                ExtraOption += " --pcd " + pcdname + '=' + pcd[3]\r
+\r
         MakefileName = self._FILE_NAME_[self._FileType]\r
         SubBuildCommandList = []\r
         MakefileName = self._FILE_NAME_[self._FileType]\r
         SubBuildCommandList = []\r
-        for A in PlatformInfo.ArchList:\r
+        for A in MyAgo.ArchList:\r
             Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}\r
             SubBuildCommandList.append(Command)\r
 \r
         MakefileTemplateDict = {\r
             "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
             "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),\r
             Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}\r
             SubBuildCommandList.append(Command)\r
 \r
         MakefileTemplateDict = {\r
             "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
             "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),\r
-            "make_path"                 : PlatformInfo.ToolDefinition["MAKE"]["PATH"],\r
-            "platform_name"             : PlatformInfo.Name,\r
-            "platform_guid"             : PlatformInfo.Guid,\r
-            "platform_version"          : PlatformInfo.Version,\r
-            "platform_build_directory"  : PlatformInfo.BuildDir,\r
+            "make_path"                 : MyAgo.ToolDefinition["MAKE"]["PATH"],\r
+            "platform_name"             : MyAgo.Name,\r
+            "platform_guid"             : MyAgo.Guid,\r
+            "platform_version"          : MyAgo.Version,\r
+            "platform_build_directory"  : MyAgo.BuildDir,\r
             "conf_directory"            : GlobalData.gConfDirectory,\r
 \r
             "conf_directory"            : GlobalData.gConfDirectory,\r
 \r
-            "toolchain_tag"             : PlatformInfo.ToolChain,\r
-            "build_target"              : PlatformInfo.BuildTarget,\r
-            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),\r
-            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),\r
-            'arch'                      : list(PlatformInfo.ArchList),\r
-            "build_architecture_list"   : ','.join(PlatformInfo.ArchList),\r
+            "toolchain_tag"             : MyAgo.ToolChain,\r
+            "build_target"              : MyAgo.BuildTarget,\r
+            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),\r
+            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),\r
+            'arch'                      : list(MyAgo.ArchList),\r
+            "build_architecture_list"   : ','.join(MyAgo.ArchList),\r
             "separator"                 : Separator,\r
             "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
             "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),\r
             "sub_build_command"         : SubBuildCommandList,\r
             "fdf_file"                  : FdfFileList,\r
             "separator"                 : Separator,\r
             "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
             "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),\r
             "sub_build_command"         : SubBuildCommandList,\r
             "fdf_file"                  : FdfFileList,\r
-            "active_platform"           : str(PlatformInfo),\r
-            "fd"                        : PlatformInfo.FdTargetList,\r
-            "fv"                        : PlatformInfo.FvTargetList,\r
-            "cap"                       : PlatformInfo.CapTargetList,\r
+            "active_platform"           : str(MyAgo),\r
+            "fd"                        : MyAgo.FdTargetList,\r
+            "fv"                        : MyAgo.FvTargetList,\r
+            "cap"                       : MyAgo.CapTargetList,\r
             "extra_options"             : ExtraOption,\r
             "macro"                     : MacroList,\r
         }\r
             "extra_options"             : ExtraOption,\r
             "macro"                     : MacroList,\r
         }\r
@@ -1325,12 +1685,10 @@ class TopLevelMakefile(BuildFile):
     def GetLibraryBuildDirectoryList(self):\r
         DirList = []\r
         for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
     def GetLibraryBuildDirectoryList(self):\r
         DirList = []\r
         for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
-            if not LibraryAutoGen.IsBinaryModule:\r
+            if not LibraryAutoGen.IsBinaryModule and not LibraryAutoGen.CanSkipbyHash():\r
                 DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))\r
         return DirList\r
 \r
                 DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))\r
         return DirList\r
 \r
-    _TemplateDict = property(_CreateTemplateDict)\r
-\r
 # This acts like the main() function for the script, unless it is 'import'ed into another script.\r
 if __name__ == '__main__':\r
     pass\r
 # This acts like the main() function for the script, unless it is 'import'ed into another script.\r
 if __name__ == '__main__':\r
     pass\r