a. Solved the force rebuild failure if there's un-recognized macro found in "#include"
authorjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 30 Jun 2008 07:15:14 +0000 (07:15 +0000)
committerjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 30 Jun 2008 07:15:14 +0000 (07:15 +0000)
b. Let the IsChanged return True as long as files' time stamp are not the same

git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1272 7335b38e-4728-0410-8992-fb3ffe349368

Source/Python/AutoGen/GenMake.py
Source/Python/Common/Misc.py

index c2d5317..71fba85 100755 (executable)
-## @file\r
-# Create makefile for MS nmake and GNU make\r
-#\r
-# Copyright (c) 2007, Intel Corporation\r
-# All rights reserved. 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
-#\r
-\r
-## Import Modules\r
-#\r
-import os\r
-import sys\r
-import string\r
-import re\r
-import os.path as path\r
-\r
-from Common.EdkIIWorkspaceBuild import *\r
-from Common.EdkIIWorkspace import *\r
-from Common.BuildToolError import *\r
-from Common.Misc import *\r
-from BuildEngine import *\r
-import Common.GlobalData as GlobalData\r
-\r
-## Regular expression for finding header file inclusions\r
-gIncludePattern = re.compile("^[ #]*include[ \t]+[\"<]*([^\"<>\n\r]+)[>\" ]*$", re.MULTILINE | 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
-\r
-## pattern for include style in R8.x code\r
-gProtocolDefinition = "Protocol/%(HeaderKey)s/%(HeaderKey)s.h"\r
-gGuidDefinition = "Guid/%(HeaderKey)s/%(HeaderKey)s.h"\r
-gArchProtocolDefinition = "ArchProtocol/%(HeaderKey)s/%(HeaderKey)s.h"\r
-gPpiDefinition = "Ppi/%(HeaderKey)s/%(HeaderKey)s.h"\r
-gIncludeMacroConversion = {\r
-  "EFI_PROTOCOL_DEFINITION"         :   gProtocolDefinition,\r
-  "EFI_GUID_DEFINITION"             :   gGuidDefinition,\r
-  "EFI_ARCH_PROTOCOL_DEFINITION"    :   gArchProtocolDefinition,\r
-  "EFI_PROTOCOL_PRODUCER"           :   gProtocolDefinition,\r
-  "EFI_PROTOCOL_CONSUMER"           :   gProtocolDefinition,\r
-  "EFI_PROTOCOL_DEPENDENCY"         :   gProtocolDefinition,\r
-  "EFI_ARCH_PROTOCOL_PRODUCER"      :   gArchProtocolDefinition,\r
-  "EFI_ARCH_PROTOCOL_CONSUMER"      :   gArchProtocolDefinition,\r
-  "EFI_ARCH_PROTOCOL_DEPENDENCY"    :   gArchProtocolDefinition,\r
-  "EFI_PPI_DEFINITION"              :   gPpiDefinition,\r
-  "EFI_PPI_PRODUCER"                :   gPpiDefinition,\r
-  "EFI_PPI_CONSUMER"                :   gPpiDefinition,\r
-  "EFI_PPI_DEPENDENCY"              :   gPpiDefinition,\r
-}\r
-\r
-## default makefile type\r
-gMakeType = ""\r
-if sys.platform == "win32":\r
-    gMakeType = "nmake"\r
-else:\r
-    gMakeType = "gmake"\r
-\r
-\r
-## BuildFile class\r
-#\r
-#  This base class encapsules build file and its generation. It uses template to generate\r
-#  the content of build file. The content of build file will be got from AutoGen objects.\r
-#\r
-class BuildFile(object):\r
-    ## template used to generate the build file (i.e. makefile if using make)\r
-    _TEMPLATE_ = ''\r
-\r
-    ## default file name for each type of build file\r
-    _FILE_NAME_ = {\r
-        "nmake" :   "Makefile",\r
-        "gmake" :   "GNUmakefile"\r
-    }\r
-\r
-    ## Fixed header string for makefile\r
-    _MAKEFILE_HEADER = '''#\r
-# DO NOT EDIT\r
-# This file is auto-generated by build utility\r
-#\r
-# Module Name:\r
-#\r
-#   %s\r
-#\r
-# Abstract:\r
-#\r
-#   Auto-generated makefile for building modules, libraries or platform\r
-#\r
-    '''\r
-\r
-    ## Header string for each type of build file\r
-    _FILE_HEADER_ = {\r
-        "nmake" :   _MAKEFILE_HEADER % _FILE_NAME_["nmake"],\r
-        "gmake" :   _MAKEFILE_HEADER % _FILE_NAME_["gmake"]\r
-    }\r
-\r
-    ## shell commands which can be used in build file in the form of macro\r
-    #   $(CP)     copy file command\r
-    #   $(MV)     move file command\r
-    #   $(RM)     remove file command\r
-    #   $(MD)     create dir command\r
-    #   $(RD)     remove dir command\r
-    #\r
-    _SHELL_CMD_ = {\r
-        "nmake" : {\r
-            "CP"    :   "copy /y",\r
-            "MV"    :   "move /y",\r
-            "RM"    :   "del /f /q",\r
-            "MD"    :   "mkdir",\r
-            "RD"    :   "rmdir /s /q",\r
-        },\r
-\r
-        "gmake" : {\r
-            "CP"    :   "cp -f",\r
-            "MV"    :   "mv -f",\r
-            "RM"    :   "rm -f",\r
-            "MD"    :   "mkdir -p",\r
-            "RD"    :   "rm -r -f",\r
-        }\r
-    }\r
-\r
-    ## directory separator\r
-    _SEP_ = {\r
-        "nmake" :   "\\",\r
-        "gmake" :   "/"\r
-    }\r
-\r
-    ## directory creation template\r
-    _MD_TEMPLATE_ = {\r
-        "nmake" :   'if not exist %(dir)s $(MD) %(dir)s',\r
-        "gmake" :   "$(MD) %(dir)s"\r
-    }\r
-\r
-    ## directory removal template\r
-    _RD_TEMPLATE_ = {\r
-        "nmake" :   'if exist %(dir)s $(RD) %(dir)s',\r
-        "gmake" :   "$(RD) %(dir)s"\r
-    }\r
-\r
-    _INC_FLAG_ = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I"}\r
-\r
-    _LIB_GROUP_START_ = {"MSFT" : "", "GCC" : "-(", "INTEL" : ""}\r
-    _LIB_GROUP_END = {"MSFT" : "", "GCC" : "-)", "INTEL" : ""}\r
-\r
-    ## Constructor of BuildFile\r
-    #\r
-    #   @param  AutoGenObject   Object of AutoGen class\r
-    #\r
-    def __init__(self, AutoGenObject):\r
-        self._AutoGenObject = AutoGenObject\r
-        self._FileType = gMakeType\r
-\r
-    ## Create build file\r
-    #\r
-    #   @param  FileType    Type of build file. Only nmake and gmake are supported now.\r
-    #\r
-    #   @retval TRUE        The build file is created or re-created successfully\r
-    #   @retval FALSE       The build file exists and is the same as the one to be generated\r
-    #\r
-    def Generate(self, FileType=gMakeType):\r
-        if FileType not in self._FILE_NAME_:\r
-            EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType)\r
-        self._FileType = FileType\r
-        FileContent = TemplateString()\r
-        FileContent.Append(self._TEMPLATE_, self._TemplateDict)\r
-\r
-        FileName = self._FILE_NAME_[FileType]\r
-        return SaveFileOnChange(os.path.join(self._AutoGenObject.MakeFileDir, FileName), str(FileContent))\r
-\r
-    ## Return a list of directory creation command string\r
-    #\r
-    #   @param      DirList     The list of directory to be created\r
-    #\r
-    #   @retval     list        The directory creation command list\r
-    #\r
-    def GetCreateDirectoryCommand(self, DirList):\r
-        return [self._MD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]\r
-\r
-    ## Return a list of directory removal command string\r
-    #\r
-    #   @param      DirList     The list of directory to be removed\r
-    #\r
-    #   @retval     list        The directory removal command list\r
-    #\r
-    def GetRemoveDirectoryCommand(self, DirList):\r
-        return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]\r
-\r
-\r
-## ModuleMakefile class\r
-#\r
-#  This class encapsules makefie and its generation for module. It uses template to generate\r
-#  the content of makefile. The content of makefile will be got from ModuleAutoGen object.\r
-#\r
-class ModuleMakefile(BuildFile):\r
-    ## template used to generate the makefile for module\r
-    _TEMPLATE_ = '''\\r
-${makefile_header}\r
-\r
-#\r
-# Platform Macro Definition\r
-#\r
-PLATFORM_NAME = ${platform_name}\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_OUTPUT_DIR = ${platform_output_directory}\r
-\r
-#\r
-# Module Macro Definition\r
-#\r
-MODULE_NAME = ${module_name}\r
-MODULE_GUID = ${module_guid}\r
-MODULE_VERSION = ${module_version}\r
-MODULE_TYPE = ${module_type}\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
-\r
-#\r
-# Build Configuration Macro Definition\r
-#\r
-ARCH = ${architecture}\r
-TOOLCHAIN_TAG = ${toolchain_tag}\r
-TARGET = ${build_target}\r
-\r
-#\r
-# Build Directory Macro Definition\r
-#\r
-# PLATFORM_BUILD_DIR = ${platform_build_directory}\r
-BUILD_DIR = ${platform_build_directory}\r
-BIN_DIR = $(BUILD_DIR)${separator}${architecture}\r
-LIB_DIR = $(BIN_DIR)\r
-MODULE_BUILD_DIR = $(BUILD_DIR)${separator}${architecture}${separator}${module_relative_directory}${separator}${module_file_base_name}\r
-OUTPUT_DIR = $(MODULE_BUILD_DIR)${separator}OUTPUT\r
-DEBUG_DIR = $(MODULE_BUILD_DIR)${separator}DEBUG\r
-DEST_DIR_OUTPUT = $(OUTPUT_DIR)\r
-DEST_DIR_DEBUG = $(DEBUG_DIR)\r
-\r
-#\r
-# Tools Flag Macro (from platform/module description file, tools_def.txt)\r
-#\r
-${BEGIN}${tool_code}_FLAGS = ${module_tool_flags}\r
-${END}\r
-\r
-#\r
-# Tools Path Macro\r
-#\r
-${BEGIN}${tool_code} = ${tool_path}\r
-${END}\r
-\r
-MAKE_FILE = ${makefile_path}\r
-\r
-#\r
-# Shell Command Macro\r
-#\r
-${BEGIN}${shell_command_code} = ${shell_command}\r
-${END}\r
-\r
-#\r
-# Build Macro\r
-#\r
-${BEGIN}${source_file_macro}\r
-${END}\r
-\r
-${BEGIN}${target_file_macro}\r
-${END}\r
-\r
-SOURCE_FILES = ${BEGIN}${source_file_macro_name} ${END}\r
-\r
-TARGET_FILES = ${BEGIN}${target_file_macro_name} ${END}\r
-\r
-INC = ${BEGIN}${include_path_prefix}${include_path} \\\r
-      ${END}\r
-\r
-#OBJECTS = ${BEGIN}$(OUTPUT_DIR)${separator}${object_file} \\\r
-#          ${END}\r
-\r
-LIBS = ${BEGIN}${library_file} \\\r
-       ${END}${BEGIN}${system_library} \\\r
-       ${END} \\\r
-       $(LIB_LIST)\r
-\r
-COMMON_DEPS = ${BEGIN}${common_dependency_file} \\\r
-              ${END}\r
-\r
-IMAGE_ENTRY_POINT = ${module_entry_point}\r
-ENTRYPOINT = ${module_entry_point}\r
-\r
-#\r
-# Overridable Target Macro Definitions\r
-#\r
-INIT_TARGET = init\r
-PCH_TARGET =\r
-CODA_TARGET = ${BEGIN}${remaining_build_target} \\\r
-              ${END}\r
-\r
-#\r
-# Default target, which will build dependent libraries in addition to source files\r
-#\r
-\r
-all: mbuild\r
-\r
-\r
-#\r
-# Target used when called from platform makefile, which will bypass the build of dependent libraries\r
-#\r
-\r
-pbuild: $(INIT_TARGET) $(PCH_TARGET) $(CODA_TARGET)\r
-\r
-#\r
-# ModuleTarget\r
-#\r
-\r
-mbuild: $(INIT_TARGET) gen_libs $(PCH_TARGET) $(CODA_TARGET)\r
-\r
-\r
-#\r
-# Target to update the FD\r
-#\r
-\r
-fds: mbuild gen_fds\r
-\r
-#\r
-# Initialization target: print build information and create necessary directories\r
-#\r
-init:\r
-\t-@echo Building ... $(MODULE_NAME) [$(ARCH)]\r
-${BEGIN}\t-@${create_directory_command}\n${END}\\r
-${BEGIN}\t-@${copy_autogen_h}\n${END}\r
-\r
-#\r
-# GenLibsTarget\r
-#\r
-gen_libs:\r
-\t${BEGIN}@cd ${dependent_library_build_directory} && "$(MAKE)" $(MAKE_FLAGS)\r
-\t${END}@cd $(MODULE_BUILD_DIR)\r
-\r
-#\r
-# Build Flash Device Image\r
-#\r
-gen_fds:\r
-\t@cd $(BUILD_DIR) && "$(MAKE)" $(MAKE_FLAGS) fds\r
-\t@cd $(MODULE_BUILD_DIR)\r
-\r
-#\r
-# Individual Object Build Targets\r
-#\r
-${BEGIN}${file_build_target}\r
-${END}\r
-\r
-\r
-#\r
-# clean all intermediate files\r
-#\r
-\r
-clean:\r
-\t${BEGIN}${clean_command}\r
-\t${END}\r
-\r
-#\r
-# clean all generated files\r
-#\r
-\r
-cleanall:\r
-${BEGIN}\t${cleanall_command}\r
-${END}\t$(RM) *.pdb *.idb > NUL 2>&1\r
-\t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi\r
-\r
-#\r
-# clean pre-compiled header files\r
-#\r
-\r
-cleanpch:\r
-\t$(RM) $(OUTPUT_DIR)\*.pch > NUL 2>&1\r
-\r
-#\r
-# clean all dependent libraries built\r
-#\r
-\r
-cleanlib:\r
-\t${BEGIN}@cd ${dependent_library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) cleanall\r
-\t${END}@cd $(MODULE_BUILD_DIR)\n'''\r
-\r
-    ## Constructor of ModuleMakefile\r
-    #\r
-    #   @param  ModuleAutoGen   Object of ModuleAutoGen class\r
-    #\r
-    def __init__(self, ModuleAutoGen):\r
-        BuildFile.__init__(self, ModuleAutoGen)\r
-        self.PlatformInfo = self._AutoGenObject.PlatformInfo\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
-\r
-        self.FileDependency = []\r
-        self.LibraryBuildCommandList = []\r
-        self.LibraryFileList = []\r
-        self.LibraryMakefileList = []\r
-        self.LibraryBuildDirectoryList = []\r
-        self.SystemLibraryList = []\r
-\r
-    # Compose a dict object containing information used to do replacement in template\r
-    def _CreateTemplateDict(self):\r
-        if self._FileType not in self._SEP_:\r
-            EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type", ExtraData=self._FileType)\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.BinaryFileDict) == 0:\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=str(self._AutoGenObject))\r
-        # convert source files and binary files to build target\r
-        if len(self._AutoGenObject.SourceFileList) > 0:\r
-            self.ProcessSourceFileList()\r
-        if len(self._AutoGenObject.BinaryFileDict) > 0:\r
-            self.ProcessBinaryFileList()\r
-\r
-        # convert dependent libaries to build command\r
-        self.ProcessDependentLibrary()\r
-        if self._AutoGenObject.Arch == "EBC":\r
-            # EBC compiler always use "EfiStart" as entry point\r
-            EntryPoint = "EfiStart"\r
-        elif self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.Module.ModuleEntryPointList) > 0:\r
-            # R8 modules use different entry point functions\r
-            EntryPoint = self._AutoGenObject.Module.ModuleEntryPointList[0]\r
-        else:\r
-            # R9 modules always use "_ModuleEntryPoint" as entry point\r
-            EntryPoint = "_ModuleEntryPoint"\r
-\r
-        DefaultToolFlag = self.PlatformInfo.ToolOption.values()\r
-        # USER_DEFINED modules should take care of tools definitions by its own\r
-        if self._AutoGenObject.ModuleType == "USER_DEFINED":\r
-            DefaultToolFlag = ["" for p in DefaultToolFlag]\r
-\r
-        if "CC" not in self.PlatformInfo.ToolChainFamily:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [CC] is not supported [%s, %s, %s]" % (self._AutoGenObject.BuildTarget,\r
-                                    self._AutoGenObject.ToolChain, self._AutoGenObject.Arch))\r
-        if  "DLINK" not in self.PlatformInfo.ToolChainFamily:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [DLINK] is not supported [%s, %s, %s]" % (self._AutoGenObject.BuildTarget,\r
-                                    self._AutoGenObject.ToolChain, self._AutoGenObject.Arch))\r
-\r
-        if self._AutoGenObject.IsLibrary:\r
-            if "Static-Library-File" in self.DestFileDatabase:\r
-                self.ResultFileList = self.DestFileDatabase["Static-Library-File"]\r
-        elif self._AutoGenObject.ModuleType == "USER_DEFINED":\r
-            if "Dynamic-Library-File" in self.DestFileDatabase:\r
-                self.ResultFileList = self.DestFileDatabase["Dynamic-Library-File"]\r
-        if len(self.ResultFileList) == 0:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Nothing found for build", ExtraData=str(self._AutoGenObject))\r
-\r
-        SourceFileMacroNameList = []\r
-        SourceFileMacroList = [] # macro name = file list\r
-        for FileType in self.SourceFileDatabase:\r
-            Macro = "%s_LIST" % FileType.replace("-", "_").upper()\r
-            SourceFileMacroNameList.append("$(%s)" % Macro)\r
-            Template = TemplateString()\r
-            Template.Append("%s = ${BEGIN}${source_file} \\\n\t${END}" % Macro,\r
-                            {"source_file" : self.SourceFileDatabase[FileType]})\r
-            SourceFileMacroList.append(str(Template))\r
-        TargetFileMacroList = []\r
-        TargetFileMacroNameList = []\r
-        for FileType in self.DestFileDatabase:\r
-            Macro = "%s_LIST" % FileType.replace("-", "_").upper()\r
-            TargetFileMacroNameList.append("$(%s)" % Macro)\r
-            Template = TemplateString()\r
-            Template.Append("%s = ${BEGIN}${target_file} \\\n\t${END}" % Macro,\r
-                            {"target_file" : self.DestFileDatabase[FileType]})\r
-            TargetFileMacroList.append(str(Template))\r
-\r
-        # R8 modules need <BaseName>StrDefs.h for string ID\r
-        if self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.UnicodeFileList) > 0:\r
-            AutoGenHeaderFile = os.path.join("$(DEBUG_DIR)", "AutoGen.h")\r
-            StringHeaderFile = os.path.join("$(DEBUG_DIR)", "%sStrDefs.h" % self._AutoGenObject.Name)\r
-            CopyAutoGenHeaderFile = ["$(CP) %s %s" % (AutoGenHeaderFile, StringHeaderFile)]\r
-        else:\r
-            CopyAutoGenHeaderFile = []\r
-\r
-        MakefileName = self._FILE_NAME_[self._FileType]\r
-        MakefileTemplateDict = {\r
-            "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
-            "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),\r
-            "platform_name"             : self.PlatformInfo.Name,\r
-            "platform_guid"             : self.PlatformInfo.Guid,\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_base_name"     : self._AutoGenObject.FileBase,\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
-\r
-            "platform_build_directory"  : self.PlatformInfo.BuildDir,\r
-\r
-            "separator"                 : Separator,\r
-            "module_tool_flags"         : [self._AutoGenObject.BuildOption[tool] for tool in self.PlatformInfo.ToolPath],\r
-\r
-            "tool_code"                 : self.PlatformInfo.ToolPath.keys(),\r
-            "tool_path"                 : self.PlatformInfo.ToolPath.values(),\r
-\r
-            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),\r
-            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),\r
-\r
-            "module_entry_point"        : EntryPoint,\r
-            "include_path_prefix"       : self._INC_FLAG_[self.PlatformInfo.ToolChainFamily["CC"]],\r
-            "dlink_output_flag"         : self.PlatformInfo.OutputFlag["DLINK"],\r
-            "slink_output_flag"         : self.PlatformInfo.OutputFlag["SLINK"],\r
-            "start_group_flag"          : self._LIB_GROUP_START_[self.PlatformInfo.ToolChainFamily["DLINK"]],\r
-            "end_group_flag"            : self._LIB_GROUP_END[self.PlatformInfo.ToolChainFamily["DLINK"]],\r
-            "include_path"              : self._AutoGenObject.IncludePathList,\r
-            "library_file"              : self.LibraryFileList,\r
-            "remaining_build_target"    : self.ResultFileList,\r
-            "system_library"            : self.SystemLibraryList,\r
-            "common_dependency_file"    : self.CommonFileDependency,\r
-            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
-            "clean_command"             : self.GetRemoveDirectoryCommand(["$(OUTPUT_DIR)"]),\r
-            "cleanall_command"          : self.GetRemoveDirectoryCommand(["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]),\r
-            "dependent_library_build_directory" : self.LibraryBuildDirectoryList,\r
-            "source_file_macro"         : SourceFileMacroList,\r
-            "target_file_macro"         : TargetFileMacroList,\r
-            "source_file_macro_name"    : SourceFileMacroNameList,\r
-            "target_file_macro_name"    : TargetFileMacroNameList,\r
-            "file_build_target"         : self.BuildTargetList,\r
-            "copy_autogen_h"            : CopyAutoGenHeaderFile,\r
-        }\r
-\r
-        return MakefileTemplateDict\r
-\r
-    ## Process source files to generate makefile targets and dependencies\r
-    #\r
-    #  The intermediate and final targets and dependencies are controlled by\r
-    #  build rules in $(WORKSPACE)/Conf/build_rule.txt. The dependencies of source\r
-    #  file are figured out by search included files in the source file.\r
-    #\r
-    def ProcessSourceFileList(self):\r
-        Separator = self._SEP_[self._FileType]\r
-\r
-        ForceIncludedFile = []\r
-        SourceFileList = []\r
-        ExtraDenpendencies = {}\r
-\r
-        if "CC" not in self.PlatformInfo.ToolChainFamily:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No CC tool found",\r
-                            ExtraData=str(self._AutoGenObject.Module))\r
-        Family = self.PlatformInfo.ToolChainFamily["CC"]\r
-        BuildRule = self.PlatformInfo.BuildRule\r
-\r
-        CCodeFlag = False\r
-        FileList = self._AutoGenObject.SourceFileList\r
-        SourceDir = os.path.join(self._AutoGenObject.WorkspaceDir, self._AutoGenObject.SourceDir)\r
-        for FileInfo in FileList:\r
-            F, SrcFileType, SrcFileBuildRule = FileInfo\r
-            # no rule, no build\r
-            if SrcFileBuildRule == None:\r
-                continue\r
-            if SrcFileType == "C-Code-File":\r
-                CCodeFlag = True\r
-            SrcFileName = path.basename(F)\r
-            SrcFileBase, SrcFileExt = path.splitext(SrcFileName)\r
-            SrcFileDir = path.dirname(F)\r
-            if SrcFileDir == "":\r
-                SrcFileDir = "."\r
-            else:\r
-                P = "$(OUTPUT_DIR)" + Separator + SrcFileDir\r
-                if P not in self.IntermediateDirectoryList:\r
-                    self.IntermediateDirectoryList.append(P)\r
-            SrcFileRelativePath = os.path.join(SourceDir, F)\r
-\r
-            SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(F, SourceDir, Separator)\r
-            if SrcFileType not in self.SourceFileDatabase:\r
-                self.SourceFileDatabase[SrcFileType] = []\r
-            self.SourceFileDatabase[SrcFileType].append(SrcFile)\r
-            SourceFileList.append(SrcFileRelativePath)\r
-            ExtraDenpendencies[SrcFileRelativePath] = ExtraSrcFileList\r
-\r
-            BuildTargetTemplate = "${BEGIN}%s : ${deps}\n"\\r
-                                  "${END}\t%s\n" % (DstFile, "\n\t".join(CommandList))\r
-            self.FileBuildTargetList.append((SrcFileRelativePath, BuildTargetTemplate))\r
-\r
-            while True:\r
-                # next target\r
-                DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)\r
-                if DstFileType == None:\r
-                    DstFileType = "Unknown-Type-File"\r
-\r
-                if DstFileType  in self.SourceFileDatabase:\r
-                    self.SourceFileDatabase[DstFileType].append(DstFile)\r
-                else:\r
-                    if DstFileType not in self.DestFileDatabase:\r
-                        self.DestFileDatabase[DstFileType] = []\r
-                    self.DestFileDatabase[DstFileType].append(DstFile)\r
-\r
-                if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:\r
-                    if DstFileBuildRule not in self.PendingBuildTargetList:\r
-                        self.PendingBuildTargetList.append(DstFileBuildRule)\r
-                    break\r
-                elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:\r
-                    self.ResultFileList.append(DstFile)\r
-                    break\r
-\r
-                SrcFile, ExtraSrcFileList, DstFile, CommandList = DstFileBuildRule.Apply(DstFile, None, Separator)\r
-                BuildTargetString = "%s : %s %s\n"\\r
-                                    "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))\r
-                self.FileBuildTargetList.append((SrcFile, BuildTargetString))\r
-                SrcFileBuildRule = DstFileBuildRule\r
-\r
-        # handle pending targets\r
-        TempBuildTargetList = []\r
-        while True:\r
-            while len(self.PendingBuildTargetList) > 0:\r
-                SrcFileBuildRule = self.PendingBuildTargetList.pop()\r
-                SrcFileList = []\r
-                for FileType in SrcFileBuildRule.SourceFileType:\r
-                    if FileType not in self.SourceFileDatabase:\r
-                        if FileType not in self.DestFileDatabase:\r
-                            continue\r
-                        else:\r
-                            SrcFileList.extend(self.DestFileDatabase[FileType])\r
-                    else:\r
-                        SrcFileList.extend(self.SourceFileDatabase[FileType])\r
-                SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(SrcFileList, None, Separator)\r
-                BuildTargetString = "%s : %s %s\n"\\r
-                                    "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))\r
-                self.FileBuildTargetList.append((SrcFile, BuildTargetString))\r
-\r
-                # try to find next target\r
-                while True:\r
-                    DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)\r
-                    if DstFileType == None:\r
-                        DstFileType = "Unknown-Type-File"\r
-\r
-                    if DstFileType  in self.SourceFileDatabase:\r
-                        self.SourceFileDatabase[DstFileType].append(DstFile)\r
-                    else:\r
-                        if DstFileType not in self.DestFileDatabase:\r
-                            self.DestFileDatabase[DstFileType] = []\r
-                        self.DestFileDatabase[DstFileType].append(DstFile)\r
-\r
-                    if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:\r
-                        TempBuildTargetList.append(DstFileBuildRule)\r
-                        break\r
-                    elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:\r
-                        self.ResultFileList.append(DstFile)\r
-                        break\r
-\r
-                    SrcFile, ExtraSrcFileList, DstFile, CommandList = DstFileBuildRule.Apply(DstFile, None, Separator)\r
-                    BuildTargetString = "%s : %s %s\n"\\r
-                                        "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))\r
-                    self.FileBuildTargetList.append((SrcFile, BuildTargetString))\r
-                    SrcFileBuildRule = DstFileBuildRule\r
-            if len(TempBuildTargetList) == 0:\r
-                break\r
-            self.PendingBuildTargetList = TempBuildTargetList\r
-\r
-        # Build AutoGen files only if we have C source files\r
-        if CCodeFlag == True:\r
-            for F in self._AutoGenObject.AutoGenFileList:\r
-                SrcFileName = path.basename(F)\r
-                SrcFileBase, SrcFileExt = path.splitext(SrcFileName)\r
-                SrcFileDir = path.dirname(F)\r
-                if SrcFileDir == "":\r
-                    SrcFileDir = "."\r
-                else:\r
-                    P = "$(DEBUG_DIR)" + Separator + SrcFileDir\r
-                    if P not in self.IntermediateDirectoryList:\r
-                        self.IntermediateDirectoryList.append(P)\r
-\r
-                SrcFileRelativePath = os.path.join(self._AutoGenObject.DebugDir, F)\r
-\r
-                SrcFileType, SrcFileBuildRule = BuildRule.Get(SrcFileExt, Family)\r
-                if SrcFileType != None and SrcFileType == "C-Header-File":\r
-                    ForceIncludedFile.append(SrcFileRelativePath)\r
-                if SrcFileBuildRule == None or SrcFileBuildRule.CommandList == []:\r
-                    continue\r
-\r
-                SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(F, self._AutoGenObject.DebugDir, Separator)\r
-\r
-                if SrcFileType not in self.SourceFileDatabase:\r
-                    self.SourceFileDatabase[SrcFileType] = []\r
-                self.SourceFileDatabase[SrcFileType].append(SrcFile)\r
-                SourceFileList.append(SrcFileRelativePath)\r
-                ExtraDenpendencies[SrcFileRelativePath] = ExtraSrcFileList\r
-\r
-                BuildTargetTemplate = "${BEGIN}%s : ${deps}\n"\\r
-                                      "${END}\t%s\n" % (DstFile, "\n\t".join(CommandList))\r
-                self.FileBuildTargetList.append((SrcFileRelativePath, BuildTargetTemplate))\r
-\r
-                while True:\r
-                    # next target\r
-                    DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)\r
-                    if DstFileType == None:\r
-                        DstFileType = "Unknown-Type-File"\r
-\r
-                    if DstFileType  in self.SourceFileDatabase:\r
-                        self.SourceFileDatabase[DstFileType].append(DstFile)\r
-                    else:\r
-                        if DstFileType not in self.DestFileDatabase:\r
-                            self.DestFileDatabase[DstFileType] = []\r
-                        self.DestFileDatabase[DstFileType].append(DstFile)\r
-\r
-                    if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:\r
-                        if DstFileBuildRule not in self.PendingBuildTargetList:\r
-                            self.PendingBuildTargetList.append(DstFileBuildRule)\r
-                        break\r
-                    elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:\r
-                        self.ResultFileList.append(DstFile)\r
-                        break\r
-\r
-                    SrcFile, ExtraSrcFileList, DstFile, CommandList = DstFileBuildRule.Apply(DstFile, None, Separator)\r
-                    BuildTargetString = "%s : %s %s\n"\\r
-                                        "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))\r
-                    self.FileBuildTargetList.append((SrcFile, BuildTargetString))\r
-                    SrcFileBuildRule = DstFileBuildRule\r
-\r
-        #\r
-        # Search dependency file list for each source file\r
-        #\r
-        self.FileDependency = self.GetFileDependency(SourceFileList, ForceIncludedFile, self._AutoGenObject.IncludePathList)\r
-        DepSet = None\r
-        for File in self.FileDependency:\r
-            if File in ExtraDenpendencies:\r
-                self.FileDependency[File] += ExtraDenpendencies[File]\r
-            # skip non-C files\r
-            if (not File.endswith(".c") and not File.endswith(".C")) or File.endswith("AutoGen.c"):\r
-                continue\r
-            elif DepSet == None:\r
-                DepSet = set(self.FileDependency[File])\r
-            else:\r
-                DepSet &= set(self.FileDependency[File])\r
-        # in case nothing in SourceFileList\r
-        if DepSet == None:\r
-            DepSet = set()\r
-        #\r
-        # Extract comman files list in the dependency files\r
-        #\r
-        self.CommonFileDependency = list(DepSet)\r
-        for File in self.FileDependency:\r
-            # skip non-C files\r
-            if (not File.endswith(".c") and not File.endswith(".C")) or File.endswith("AutoGen.c"):\r
-                continue\r
-            NewDepSet = set(self.FileDependency[File])\r
-            NewDepSet -= DepSet\r
-            self.FileDependency[File] = ["$(COMMON_DEPS)"] + list(NewDepSet)\r
-\r
-        # EdkLogger.verbose("Files to be built in %s :\n\t %s\n" % (str(self._AutoGenObject), "\n\t".join(self.FileDependency.keys())))\r
-        for File, TargetTemplate in self.FileBuildTargetList:\r
-            if File not in self.FileDependency:\r
-                self.BuildTargetList.append(TargetTemplate)\r
-                continue\r
-            Template = TemplateString()\r
-            Template.Append(TargetTemplate, {"deps" : self.FileDependency[File]})\r
-            self.BuildTargetList.append(str(Template))\r
-\r
-\r
-    ## Process binary files to generate makefile targets and dependencies\r
-    #\r
-    # All binary files are just copied to $(OUTPUT_DIR)\r
-    #\r
-    def ProcessBinaryFileList(self):\r
-        BinaryFiles = self._AutoGenObject.BinaryFileDict\r
-        BuildTargetString = "%(dst)s : %(src)s\n"\\r
-                            "\t$(CP) %(src)s %(dst)s\n"\r
-        for FileType in BinaryFiles:\r
-            if FileType not in self.DestFileDatabase:\r
-                self.DestFileDatabase[FileType] = []\r
-            for F in BinaryFiles[FileType]:\r
-                Src = os.path.join("$(MODULE_DIR)", F)\r
-                FileName = os.path.basename(F)\r
-                Dst = os.path.join("$(OUTPUT_DIR)", FileName)\r
-                self.DestFileDatabase[FileType].append(Dst)\r
-                self.ResultFileList.append(Dst)\r
-                self.BuildTargetList.append(BuildTargetString % {"dst":Dst, "src":Src})\r
-\r
-    ## For creating makefile targets for dependent libraries\r
-    def ProcessDependentLibrary(self):\r
-        for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
-            self.LibraryBuildDirectoryList.append(LibraryAutoGen.BuildDir)\r
-            self.LibraryFileList.append(os.path.join(LibraryAutoGen.OutputDir, LibraryAutoGen.Name + ".lib"))\r
-\r
-    ## Return a list containing source file's dependencies\r
-    #\r
-    #   @param      FileList        The list of source files\r
-    #   @param      ForceInculeList The list of files which will be included forcely\r
-    #   @param      SearchPathList  The list of search path\r
-    #\r
-    #   @retval     dict            The mapping between source file path and its dependencies\r
-    #\r
-    def GetFileDependency(self, FileList, ForceInculeList, SearchPathList):\r
-        Dependency = {}\r
-        for F in FileList:\r
-            Dependency[F] = self.GetDependencyList(F, ForceInculeList, SearchPathList)\r
-        return Dependency\r
-\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
-    #  in given search path list.\r
-    #\r
-    #   @param      File            The source file\r
-    #   @param      ForceInculeList The list of files which will be included forcely\r
-    #   @param      SearchPathList  The list of search path\r
-    #\r
-    #   @retval     list            The list of files the given source file depends on\r
-    #\r
-    def GetDependencyList(self, File, ForceList, SearchPathList):\r
-        EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File)\r
-        EdkLogger.debug(EdkLogger.DEBUG_0, "Including %s" % " ".join(ForceList))\r
-        FileStack = [File] + ForceList\r
-        DependencySet = set()\r
-        MacroUsedByIncludedFile = False\r
-\r
-        if self._AutoGenObject.Arch not in gDependencyDatabase:\r
-            gDependencyDatabase[self._AutoGenObject.Arch] = {}\r
-        DepDb = gDependencyDatabase[self._AutoGenObject.Arch]\r
-        while len(FileStack) > 0:\r
-            EdkLogger.debug(EdkLogger.DEBUG_0, "Stack %s" % "\n\t".join(FileStack))\r
-            F = FileStack.pop()\r
-\r
-            CurrentFileDependencyList = []\r
-            if F in DepDb and not IsChanged(F):\r
-                CurrentFileDependencyList = DepDb[F]\r
-                for Dep in CurrentFileDependencyList:\r
-                    if Dep not in FileStack and Dep not in DependencySet:\r
-                        FileStack.append(Dep)\r
-            else:\r
-                try:\r
-                    Fd = open(F, 'r')\r
-                except:\r
-                    EdkLogger.error("AutoGen", FILE_OPEN_FAILURE, ExtraData=F)\r
-\r
-                FileContent = Fd.read()\r
-                Fd.close()\r
-                if len(FileContent) == 0:\r
-                    continue\r
-\r
-                if FileContent[0] == 0xff or FileContent[0] == 0xfe:\r
-                    FileContent = unicode(FileContent, "utf-16")\r
-                IncludedFileList = gIncludePattern.findall(FileContent)\r
-\r
-                CurrentFilePath = os.path.dirname(F)\r
-                for Inc in IncludedFileList:\r
-                    # if there's macro used to reference header file, expand it\r
-                    HeaderList = gMacroPattern.findall(Inc)\r
-                    if len(HeaderList) == 1 and len(HeaderList[0]) == 2:\r
-                        HeaderType = HeaderList[0][0]\r
-                        HeaderKey = HeaderList[0][1]\r
-                        if HeaderType in gIncludeMacroConversion:\r
-                            Inc = gIncludeMacroConversion[HeaderType] % {"HeaderKey" : HeaderKey}\r
-                        else:\r
-                            # not known macro used in #include\r
-                            MacroUsedByIncludedFile = True\r
-                            continue\r
-                    Inc = os.path.normpath(Inc)\r
-                    for SearchPath in [CurrentFilePath] + SearchPathList:\r
-                        FilePath = os.path.join(SearchPath, Inc)\r
-                        if not os.path.exists(FilePath) or FilePath in CurrentFileDependencyList:\r
-                            continue\r
-                        CurrentFileDependencyList.append(FilePath)\r
-                        if FilePath not in FileStack and FilePath not in DependencySet:\r
-                            FileStack.append(FilePath)\r
-                        break\r
-                    else:\r
-                        EdkLogger.verbose("%s included by %s was not found in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList)))\r
-\r
-                if not MacroUsedByIncludedFile:\r
-                    if F == File:\r
-                        CurrentFileDependencyList += ForceList\r
-                    #\r
-                    # Don't keep the file in cache if it uses macro in included file.\r
-                    # So it will be scanned again if another file includes this file.\r
-                    #\r
-                    DepDb[F] = CurrentFileDependencyList\r
-            DependencySet.update(CurrentFileDependencyList)\r
-\r
-        #\r
-        # If there's macro used in included file, always build the file by\r
-        # returning a empty dependency\r
-        #\r
-        if MacroUsedByIncludedFile:\r
-            DependencyList = [""]\r
-        else:\r
-            DependencyList = list(DependencySet)  # remove duplicate ones\r
-            DependencyList.append(File)\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
-#  the content of makefile. The content of makefile will be got from ModuleAutoGen object.\r
-#\r
-class CustomMakefile(BuildFile):\r
-    ## template used to generate the makefile for module with custom makefile\r
-    _TEMPLATE_ = '''\\r
-${makefile_header}\r
-\r
-#\r
-# Platform Macro Definition\r
-#\r
-PLATFORM_NAME = ${platform_name}\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_OUTPUT_DIR = ${platform_output_directory}\r
-\r
-#\r
-# Module Macro Definition\r
-#\r
-MODULE_NAME = ${module_name}\r
-MODULE_GUID = ${module_guid}\r
-MODULE_VERSION = ${module_version}\r
-MODULE_TYPE = ${module_type}\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
-\r
-#\r
-# Build Configuration Macro Definition\r
-#\r
-ARCH = ${architecture}\r
-TOOLCHAIN_TAG = ${toolchain_tag}\r
-TARGET = ${build_target}\r
-\r
-#\r
-# Build Directory Macro Definition\r
-#\r
-# PLATFORM_BUILD_DIR = ${platform_build_directory}\r
-BUILD_DIR = ${platform_build_directory}\r
-BIN_DIR = $(BUILD_DIR)${separator}${architecture}\r
-LIB_DIR = $(BIN_DIR)\r
-MODULE_BUILD_DIR = $(BUILD_DIR)${separator}${architecture}${separator}${module_relative_directory}${separator}${module_file_base_name}\r
-OUTPUT_DIR = $(MODULE_BUILD_DIR)${separator}OUTPUT\r
-DEBUG_DIR = $(MODULE_BUILD_DIR)${separator}DEBUG\r
-DEST_DIR_OUTPUT = $(OUTPUT_DIR)\r
-DEST_DIR_DEBUG = $(DEBUG_DIR)\r
-\r
-#\r
-# Tools Flag Macro (from platform/module description file, tools_def.txt)\r
-#\r
-${BEGIN}${tool_code}_FLAGS = ${module_tool_flags}\r
-${END}\r
-\r
-#\r
-# Tools Path Macro\r
-#\r
-${BEGIN}${tool_code} = ${tool_path}\r
-${END}\r
-\r
-MAKE_FILE = ${makefile_path}\r
-\r
-#\r
-# Shell Command Macro\r
-#\r
-${BEGIN}${shell_command_code} = ${shell_command}\r
-${END}\r
-\r
-${custom_makefile_content}\r
-\r
-#\r
-# Target used when called from platform makefile, which will bypass the build of dependent libraries\r
-#\r
-\r
-pbuild: init all\r
-\r
-\r
-#\r
-# ModuleTarget\r
-#\r
-\r
-mbuild: init all\r
-\r
-\r
-#\r
-# Initialization target: print build information and create necessary directories\r
-#\r
-init:\r
-\t-@echo Building ... $(MODULE_NAME) [$(ARCH)]\r
-${BEGIN}\t-@${create_directory_command}\n${END}\\r
-\r
-'''\r
-    ## Constructor of CustomMakefile\r
-    #\r
-    #   @param  ModuleAutoGen   Object of ModuleAutoGen class\r
-    #\r
-    def __init__(self, ModuleAutoGen):\r
-        BuildFile.__init__(self, ModuleAutoGen)\r
-        self.PlatformInfo = self._AutoGenObject.PlatformInfo\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
-        Separator = self._SEP_[self._FileType]\r
-        try:\r
-            if self._FileType not in self._AutoGenObject.CustomMakefile:\r
-                EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,\r
-                                ExtraData=str(self._AutoGenObject))\r
-            MakefilePath = os.path.join(\r
-                                    self._AutoGenObject.WorkspaceDir,\r
-                                    self._AutoGenObject.CustomMakefile[self._FileType]\r
-                                    )\r
-            CustomMakefile = open(MakefilePath, 'r').read()\r
-        except:\r
-            EdkLogger.error('build', FILE_OPEN_FAILURE, ExtraData=self._AutoGenObject.CustomMakefile[self._FileType])\r
-\r
-        MakefileName = self._FILE_NAME_[self._FileType]\r
-        MakefileTemplateDict = {\r
-            "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
-            "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),\r
-            "platform_name"             : self.PlatformInfo.Name,\r
-            "platform_guid"             : self.PlatformInfo.Guid,\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_base_name"     : self._AutoGenObject.FileBase,\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
-\r
-            "platform_build_directory"  : self.PlatformInfo.BuildDir,\r
-\r
-            "separator"                 : Separator,\r
-            "module_tool_flags"         : [self._AutoGenObject.BuildOption[tool] for tool in self.PlatformInfo.ToolPath],\r
-\r
-            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),\r
-            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),\r
-\r
-            "tool_code"                 : self.PlatformInfo.ToolPath.keys(),\r
-            "tool_path"                 : self.PlatformInfo.ToolPath.values(),\r
-\r
-            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
-            "custom_makefile_content"   : CustomMakefile\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
-# template to generate the content of makefile. The content of makefile will be\r
-# got from PlatformAutoGen object.\r
-#\r
-class PlatformMakefile(BuildFile):\r
-    ## template used to generate the makefile for platform\r
-    _TEMPLATE_ = '''\\r
-${makefile_header}\r
-\r
-#\r
-# Platform Macro Definition\r
-#\r
-PLATFORM_NAME = ${platform_name}\r
-PLATFORM_GUID = ${platform_guid}\r
-PLATFORM_VERSION = ${platform_version}\r
-PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
-PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
-\r
-#\r
-# Build Configuration Macro Definition\r
-#\r
-TOOLCHAIN_TAG = ${toolchain_tag}\r
-TARGET = ${build_target}\r
-\r
-#\r
-# Build Directory Macro Definition\r
-#\r
-BUILD_DIR = ${platform_build_directory}\r
-FV_DIR = ${platform_build_directory}${separator}FV\r
-\r
-#\r
-# Shell Command Macro\r
-#\r
-${BEGIN}${shell_command_code} = ${shell_command}\r
-${END}\r
-\r
-MAKE = ${make_path}\r
-MAKE_FLAGS = ${make_flag}\r
-MAKE_FILE = ${makefile_path}\r
-\r
-#\r
-# Default target\r
-#\r
-all: init build_libraries build_modules\r
-\r
-#\r
-# Initialization target: print build information and create necessary directories\r
-#\r
-init:\r
-\t-@echo Building ... $(PLATFORM_NAME) [${build_architecture_list}]\r
-\t${BEGIN}-@${create_directory_command}\r
-\t${END}\r
-#\r
-# library build target\r
-#\r
-libraries: init build_libraries\r
-\r
-#\r
-# module build target\r
-#\r
-modules: init build_libraries build_modules\r
-\r
-#\r
-# Build all libraries:\r
-#\r
-build_libraries:\r
-${BEGIN}\t@cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) pbuild\r
-${END}\t@cd $(BUILD_DIR)\r
-\r
-#\r
-# Build all modules:\r
-#\r
-build_modules:\r
-${BEGIN}\t@cd ${module_build_directory} && "$(MAKE)" $(MAKE_FLAGS) pbuild\r
-${END}\t@cd $(BUILD_DIR)\r
-\r
-#\r
-# Clean intermediate files\r
-#\r
-clean:\r
-\t${BEGIN}@cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) clean\r
-\t${END}${BEGIN}@cd ${module_build_directory} && "$(MAKE)" $(MAKE_FLAGS) clean\r
-\t${END}@cd $(BUILD_DIR)\r
-\r
-#\r
-# Clean all generated files except to makefile\r
-#\r
-cleanall:\r
-${BEGIN}\t${cleanall_command}\r
-${END}\r
-\r
-#\r
-# Clean all library files\r
-#\r
-cleanlib:\r
-\t${BEGIN}@cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) cleanall\r
-\t${END}@cd $(BUILD_DIR)\n\r
-'''\r
-\r
-    ## Constructor of PlatformMakefile\r
-    #\r
-    #   @param  ModuleAutoGen   Object of PlatformAutoGen class\r
-    #\r
-    def __init__(self, PlatformAutoGen):\r
-        BuildFile.__init__(self, PlatformAutoGen)\r
-        self.ModuleBuildCommandList = []\r
-        self.ModuleMakefileList = []\r
-        self.IntermediateDirectoryList = []\r
-        self.ModuleBuildDirectoryList = []\r
-        self.LibraryBuildDirectoryList = []\r
-\r
-    # Compose a dict object containing information used to do replacement in template\r
-    def _CreateTemplateDict(self):\r
-        Separator = self._SEP_[self._FileType]\r
-\r
-        PlatformInfo = self._AutoGenObject\r
-        if "MAKE" not in PlatformInfo.ToolPath:\r
-            EdkLogger.error("GenMake", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!")\r
-\r
-        self.IntermediateDirectoryList = ["$(BUILD_DIR)"]\r
-        self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()\r
-        self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()\r
-\r
-        MakefileName = self._FILE_NAME_[self._FileType]\r
-        MakefileTemplateDict = {\r
-            "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
-            "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),\r
-            "platform_name"             : PlatformInfo.Name,\r
-            "platform_guid"             : PlatformInfo.Guid,\r
-            "platform_version"          : PlatformInfo.Version,\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
-            "make_path"                 : PlatformInfo.ToolPath["MAKE"],\r
-            "make_flag"                 : PlatformInfo.ToolOption["MAKE"],\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
-            "separator"                 : Separator,\r
-            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
-            "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),\r
-            "library_build_directory"   : self.LibraryBuildDirectoryList,\r
-            "module_build_directory"    : self.ModuleBuildDirectoryList,\r
-            "active_platform"           : PlatformInfo.WorkspaceDir + Separator + str(PlatformInfo),\r
-        }\r
-\r
-        return MakefileTemplateDict\r
-\r
-    ## Get the root directory list for intermediate files of all modules build\r
-    #\r
-    #   @retval     list    The list of directory\r
-    #\r
-    def GetModuleBuildDirectoryList(self):\r
-        DirList = []\r
-        for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:\r
-            DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))\r
-        return DirList\r
-\r
-    ## Get the root directory list for intermediate files of all libraries build\r
-    #\r
-    #   @retval     list    The list of directory\r
-    #\r
-    def GetLibraryBuildDirectoryList(self):\r
-        DirList = []\r
-        for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\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
-# uses template to generate the content of makefile. The content of makefile\r
-# will be got from WorkspaceAutoGen object.\r
-#\r
-class TopLevelMakefile(BuildFile):\r
-    ## template used to generate toplevel makefile\r
-    _TEMPLATE_ = '''\\r
-${makefile_header}\r
-\r
-#\r
-# Platform Macro Definition\r
-#\r
-PLATFORM_NAME = ${platform_name}\r
-PLATFORM_GUID = ${platform_guid}\r
-PLATFORM_VERSION = ${platform_version}\r
-\r
-#\r
-# Build Configuration Macro Definition\r
-#\r
-TOOLCHAIN_TAG = ${toolchain_tag}\r
-TARGET = ${build_target}\r
-\r
-#\r
-# Build Directory Macro Definition\r
-#\r
-BUILD_DIR = ${platform_build_directory}\r
-FV_DIR = ${platform_build_directory}${separator}FV\r
-\r
-#\r
-# Shell Command Macro\r
-#\r
-${BEGIN}${shell_command_code} = ${shell_command}\r
-${END}\r
-\r
-MAKE = ${make_path}\r
-MAKE_FLAGS = ${make_flag}\r
-MAKE_FILE = ${makefile_path}\r
-\r
-#\r
-# Default target\r
-#\r
-all: modules fds\r
-\r
-#\r
-# Initialization target: print build information and create necessary directories\r
-#\r
-init:\r
-\t-@echo Building ... $(PLATFORM_NAME) [${build_architecture_list}]\r
-\t${BEGIN}-@${create_directory_command}\r
-\t${END}\r
-#\r
-# library build target\r
-#\r
-libraries: init\r
-${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) libraries\r
-${END}\t@cd $(BUILD_DIR)\r
-\r
-#\r
-# module build target\r
-#\r
-modules: init\r
-${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) modules\r
-${END}\t@cd $(BUILD_DIR)\r
-\r
-#\r
-# Flash Device Image Target\r
-#\r
-fds: init\r
-\t-@cd $(FV_DIR)\r
-${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN_TAG) -b $(TARGET) -p ${active_platform} -a ${build_architecture_list} ${log_level}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -y ${macro} ${END}\r
-\r
-#\r
-# run command for emulator platform only\r
-#\r
-run:\r
-\tcd $(BUILD_DIR)${separator}IA32\r
-\tSecMain\r
-\tcd $(BUILD_DIR)\r
-\r
-#\r
-# Clean intermediate files\r
-#\r
-clean:\r
-${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) clean\r
-${END}\t@cd $(BUILD_DIR)\r
-\r
-#\r
-# Clean all generated files except to makefile\r
-#\r
-cleanall:\r
-${BEGIN}\t${cleanall_command}\r
-${END}\r
-\r
-#\r
-# Clean all library files\r
-#\r
-cleanlib:\r
-${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) cleanlib\r
-${END}\t@cd $(BUILD_DIR)\n\r
-'''\r
-\r
-    ## Constructor of TopLevelMakefile\r
-    #\r
-    #   @param  Workspace   Object of WorkspaceAutoGen class\r
-    #\r
-    def __init__(self, Workspace):\r
-        BuildFile.__init__(self, Workspace)\r
-        self.IntermediateDirectoryList = []\r
-\r
-    # Compose a dict object containing information used to do replacement in template\r
-    def _CreateTemplateDict(self):\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
-\r
-        if "MAKE" not in PlatformInfo.ToolPath:\r
-            EdkLogger.error("GenMake", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!")\r
-\r
-        for Arch in PlatformInfo.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
-        if PlatformInfo.FdfFile != None and PlatformInfo.FdfFile != "":\r
-            FdfFileList = [PlatformInfo.FdfFile]\r
-            # macros passed to GenFds\r
-            for MacroName in GlobalData.gGlobalDefines:\r
-                MacroList.append('"%s=%s"' % (MacroName, GlobalData.gGlobalDefines[MacroName]))\r
-        else:\r
-            FdfFileList = []\r
-\r
-        # pass log level to external program called in makefile, currently GenFds.exe\r
-        LogLevel = EdkLogger.GetLevel()\r
-        if LogLevel == EdkLogger.VERBOSE:\r
-            LogOption = "-v"\r
-        elif LogLevel <= EdkLogger.DEBUG_9:\r
-            LogOption = "-d %d" % (LogLevel - 1)\r
-        elif LogLevel == EdkLogger.QUIET:\r
-            LogOption = "-q"\r
-        else:\r
-            LogOption = ""\r
-\r
-        MakefileName = self._FILE_NAME_[self._FileType]\r
-        MakefileTemplateDict = {\r
-            "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
-            "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),\r
-            "platform_name"             : PlatformInfo.Name,\r
-            "platform_guid"             : PlatformInfo.Guid,\r
-            "platform_version"          : PlatformInfo.Version,\r
-            "platform_build_directory"  : PlatformInfo.BuildDir,\r
-\r
-            "toolchain_tag"             : PlatformInfo.ToolChain,\r
-            "build_target"              : PlatformInfo.BuildTarget,\r
-            "make_path"                 : PlatformInfo.ToolPath["MAKE"],\r
-            "make_flag"                 : PlatformInfo.ToolOption["MAKE"],\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
-            "separator"                 : Separator,\r
-            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
-            "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),\r
-            "fdf_file"                  : FdfFileList,\r
-            "active_platform"           : PlatformInfo.WorkspaceDir + Separator + str(PlatformInfo),\r
-            "fd"                        : PlatformInfo.FdTargetList,\r
-            "fv"                        : PlatformInfo.FvTargetList,\r
-            "log_level"                 : LogOption,\r
-            "macro"                     : MacroList,\r
-        }\r
-\r
-        return MakefileTemplateDict\r
-\r
-    ## Get the root directory list for intermediate files of all modules build\r
-    #\r
-    #   @retval     list    The list of directory\r
-    #\r
-    def GetModuleBuildDirectoryList(self):\r
-        DirList = []\r
-        for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:\r
-            DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))\r
-        return DirList\r
-\r
-    ## Get the root directory list for intermediate files of all libraries build\r
-    #\r
-    #   @retval     list    The list of directory\r
-    #\r
-    def GetLibraryBuildDirectoryList(self):\r
-        DirList = []\r
-        for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\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
-\r
+## @file
+# Create makefile for MS nmake and GNU make
+#
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+## Import Modules
+#
+import os
+import sys
+import string
+import re
+import os.path as path
+
+from Common.EdkIIWorkspaceBuild import *
+from Common.EdkIIWorkspace import *
+from Common.BuildToolError import *
+from Common.Misc import *
+from BuildEngine import *
+import Common.GlobalData as GlobalData
+
+## Regular expression for finding header file inclusions
+gIncludePattern = re.compile("^[ #]*include[ \t]+[\"<]*([^\"<>\n\r]+)[>\" ]*$", re.MULTILINE | re.UNICODE)
+
+## Regular expression for matching macro used in header file inclusion
+gMacroPattern = re.compile("([_A-Z][_A-Z0-9]*)[ \t]*\((.+)\)", re.UNICODE)
+
+## pattern for include style in R8.x code
+gProtocolDefinition = "Protocol/%(HeaderKey)s/%(HeaderKey)s.h"
+gGuidDefinition = "Guid/%(HeaderKey)s/%(HeaderKey)s.h"
+gArchProtocolDefinition = "ArchProtocol/%(HeaderKey)s/%(HeaderKey)s.h"
+gPpiDefinition = "Ppi/%(HeaderKey)s/%(HeaderKey)s.h"
+gIncludeMacroConversion = {
+  "EFI_PROTOCOL_DEFINITION"         :   gProtocolDefinition,
+  "EFI_GUID_DEFINITION"             :   gGuidDefinition,
+  "EFI_ARCH_PROTOCOL_DEFINITION"    :   gArchProtocolDefinition,
+  "EFI_PROTOCOL_PRODUCER"           :   gProtocolDefinition,
+  "EFI_PROTOCOL_CONSUMER"           :   gProtocolDefinition,
+  "EFI_PROTOCOL_DEPENDENCY"         :   gProtocolDefinition,
+  "EFI_ARCH_PROTOCOL_PRODUCER"      :   gArchProtocolDefinition,
+  "EFI_ARCH_PROTOCOL_CONSUMER"      :   gArchProtocolDefinition,
+  "EFI_ARCH_PROTOCOL_DEPENDENCY"    :   gArchProtocolDefinition,
+  "EFI_PPI_DEFINITION"              :   gPpiDefinition,
+  "EFI_PPI_PRODUCER"                :   gPpiDefinition,
+  "EFI_PPI_CONSUMER"                :   gPpiDefinition,
+  "EFI_PPI_DEPENDENCY"              :   gPpiDefinition,
+}
+
+## default makefile type
+gMakeType = ""
+if sys.platform == "win32":
+    gMakeType = "nmake"
+else:
+    gMakeType = "gmake"
+
+
+## BuildFile class
+#
+#  This base class encapsules build file and its generation. It uses template to generate
+#  the content of build file. The content of build file will be got from AutoGen objects.
+#
+class BuildFile(object):
+    ## template used to generate the build file (i.e. makefile if using make)
+    _TEMPLATE_ = ''
+
+    ## default file name for each type of build file
+    _FILE_NAME_ = {
+        "nmake" :   "Makefile",
+        "gmake" :   "GNUmakefile"
+    }
+
+    ## Fixed header string for makefile
+    _MAKEFILE_HEADER = '''#
+# DO NOT EDIT
+# This file is auto-generated by build utility
+#
+# Module Name:
+#
+#   %s
+#
+# Abstract:
+#
+#   Auto-generated makefile for building modules, libraries or platform
+#
+    '''
+
+    ## Header string for each type of build file
+    _FILE_HEADER_ = {
+        "nmake" :   _MAKEFILE_HEADER % _FILE_NAME_["nmake"],
+        "gmake" :   _MAKEFILE_HEADER % _FILE_NAME_["gmake"]
+    }
+
+    ## shell commands which can be used in build file in the form of macro
+    #   $(CP)     copy file command
+    #   $(MV)     move file command
+    #   $(RM)     remove file command
+    #   $(MD)     create dir command
+    #   $(RD)     remove dir command
+    #
+    _SHELL_CMD_ = {
+        "nmake" : {
+            "CP"    :   "copy /y",
+            "MV"    :   "move /y",
+            "RM"    :   "del /f /q",
+            "MD"    :   "mkdir",
+            "RD"    :   "rmdir /s /q",
+        },
+
+        "gmake" : {
+            "CP"    :   "cp -f",
+            "MV"    :   "mv -f",
+            "RM"    :   "rm -f",
+            "MD"    :   "mkdir -p",
+            "RD"    :   "rm -r -f",
+        }
+    }
+
+    ## directory separator
+    _SEP_ = {
+        "nmake" :   "\\",
+        "gmake" :   "/"
+    }
+
+    ## directory creation template
+    _MD_TEMPLATE_ = {
+        "nmake" :   'if not exist %(dir)s $(MD) %(dir)s',
+        "gmake" :   "$(MD) %(dir)s"
+    }
+
+    ## directory removal template
+    _RD_TEMPLATE_ = {
+        "nmake" :   'if exist %(dir)s $(RD) %(dir)s',
+        "gmake" :   "$(RD) %(dir)s"
+    }
+
+    _INC_FLAG_ = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I"}
+
+    _LIB_GROUP_START_ = {"MSFT" : "", "GCC" : "-(", "INTEL" : ""}
+    _LIB_GROUP_END = {"MSFT" : "", "GCC" : "-)", "INTEL" : ""}
+
+    ## Constructor of BuildFile
+    #
+    #   @param  AutoGenObject   Object of AutoGen class
+    #
+    def __init__(self, AutoGenObject):
+        self._AutoGenObject = AutoGenObject
+        self._FileType = gMakeType
+
+    ## Create build file
+    #
+    #   @param  FileType    Type of build file. Only nmake and gmake are supported now.
+    #
+    #   @retval TRUE        The build file is created or re-created successfully
+    #   @retval FALSE       The build file exists and is the same as the one to be generated
+    #
+    def Generate(self, FileType=gMakeType):
+        if FileType not in self._FILE_NAME_:
+            EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType)
+        self._FileType = FileType
+        FileContent = TemplateString()
+        FileContent.Append(self._TEMPLATE_, self._TemplateDict)
+
+        FileName = self._FILE_NAME_[FileType]
+        return SaveFileOnChange(os.path.join(self._AutoGenObject.MakeFileDir, FileName), str(FileContent))
+
+    ## Return a list of directory creation command string
+    #
+    #   @param      DirList     The list of directory to be created
+    #
+    #   @retval     list        The directory creation command list
+    #
+    def GetCreateDirectoryCommand(self, DirList):
+        return [self._MD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
+
+    ## Return a list of directory removal command string
+    #
+    #   @param      DirList     The list of directory to be removed
+    #
+    #   @retval     list        The directory removal command list
+    #
+    def GetRemoveDirectoryCommand(self, DirList):
+        return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
+
+
+## ModuleMakefile class
+#
+#  This class encapsules makefie and its generation for module. It uses template to generate
+#  the content of makefile. The content of makefile will be got from ModuleAutoGen object.
+#
+class ModuleMakefile(BuildFile):
+    ## template used to generate the makefile for module
+    _TEMPLATE_ = '''\
+${makefile_header}
+
+#
+# Platform Macro Definition
+#
+PLATFORM_NAME = ${platform_name}
+PLATFORM_GUID = ${platform_guid}
+PLATFORM_VERSION = ${platform_version}
+PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
+PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
+PLATFORM_OUTPUT_DIR = ${platform_output_directory}
+
+#
+# Module Macro Definition
+#
+MODULE_NAME = ${module_name}
+MODULE_GUID = ${module_guid}
+MODULE_VERSION = ${module_version}
+MODULE_TYPE = ${module_type}
+MODULE_FILE_BASE_NAME = ${module_file_base_name}
+BASE_NAME = $(MODULE_NAME)
+MODULE_RELATIVE_DIR = ${module_relative_directory}
+MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
+
+#
+# Build Configuration Macro Definition
+#
+ARCH = ${architecture}
+TOOLCHAIN_TAG = ${toolchain_tag}
+TARGET = ${build_target}
+
+#
+# Build Directory Macro Definition
+#
+# PLATFORM_BUILD_DIR = ${platform_build_directory}
+BUILD_DIR = ${platform_build_directory}
+BIN_DIR = $(BUILD_DIR)${separator}${architecture}
+LIB_DIR = $(BIN_DIR)
+MODULE_BUILD_DIR = $(BUILD_DIR)${separator}${architecture}${separator}${module_relative_directory}${separator}${module_file_base_name}
+OUTPUT_DIR = $(MODULE_BUILD_DIR)${separator}OUTPUT
+DEBUG_DIR = $(MODULE_BUILD_DIR)${separator}DEBUG
+DEST_DIR_OUTPUT = $(OUTPUT_DIR)
+DEST_DIR_DEBUG = $(DEBUG_DIR)
+
+#
+# Tools Flag Macro (from platform/module description file, tools_def.txt)
+#
+${BEGIN}${tool_code}_FLAGS = ${module_tool_flags}
+${END}
+
+#
+# Tools Path Macro
+#
+${BEGIN}${tool_code} = ${tool_path}
+${END}
+
+MAKE_FILE = ${makefile_path}
+
+#
+# Shell Command Macro
+#
+${BEGIN}${shell_command_code} = ${shell_command}
+${END}
+
+#
+# Build Macro
+#
+${BEGIN}${source_file_macro}
+${END}
+
+${BEGIN}${target_file_macro}
+${END}
+
+SOURCE_FILES = ${BEGIN}${source_file_macro_name} ${END}
+
+TARGET_FILES = ${BEGIN}${target_file_macro_name} ${END}
+
+INC = ${BEGIN}${include_path_prefix}${include_path} \\
+      ${END}
+
+#OBJECTS = ${BEGIN}$(OUTPUT_DIR)${separator}${object_file} \\
+#          ${END}
+
+LIBS = ${BEGIN}${library_file} \\
+       ${END}${BEGIN}${system_library} \\
+       ${END} \\
+       $(LIB_LIST)
+
+COMMON_DEPS = ${BEGIN}${common_dependency_file} \\
+              ${END}
+
+IMAGE_ENTRY_POINT = ${module_entry_point}
+ENTRYPOINT = ${module_entry_point}
+
+#
+# Overridable Target Macro Definitions
+#
+FORCE_REBUILD = force_build
+INIT_TARGET = init
+PCH_TARGET =
+CODA_TARGET = ${BEGIN}${remaining_build_target} \\
+              ${END}
+
+#
+# Default target, which will build dependent libraries in addition to source files
+#
+
+all: mbuild
+
+
+#
+# Target used when called from platform makefile, which will bypass the build of dependent libraries
+#
+
+pbuild: $(INIT_TARGET) $(PCH_TARGET) $(CODA_TARGET)
+
+#
+# ModuleTarget
+#
+
+mbuild: $(INIT_TARGET) gen_libs $(PCH_TARGET) $(CODA_TARGET)
+
+#
+# Phony target which is used to force executing commands for a target
+#
+force_build:
+\t-@
+
+#
+# Target to update the FD
+#
+
+fds: mbuild gen_fds
+
+#
+# Initialization target: print build information and create necessary directories
+#
+init:
+\t-@echo Building ... $(MODULE_NAME) [$(ARCH)]
+${BEGIN}\t-@${create_directory_command}\n${END}\
+${BEGIN}\t-@${copy_autogen_h}\n${END}
+
+#
+# GenLibsTarget
+#
+gen_libs:
+\t${BEGIN}@cd ${dependent_library_build_directory} && "$(MAKE)" $(MAKE_FLAGS)
+\t${END}@cd $(MODULE_BUILD_DIR)
+
+#
+# Build Flash Device Image
+#
+gen_fds:
+\t@cd $(BUILD_DIR) && "$(MAKE)" $(MAKE_FLAGS) fds
+\t@cd $(MODULE_BUILD_DIR)
+
+#
+# Individual Object Build Targets
+#
+${BEGIN}${file_build_target}
+${END}
+
+
+#
+# clean all intermediate files
+#
+
+clean:
+\t${BEGIN}${clean_command}
+\t${END}
+
+#
+# clean all generated files
+#
+
+cleanall:
+${BEGIN}\t${cleanall_command}
+${END}\t$(RM) *.pdb *.idb > NUL 2>&1
+\t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi
+
+#
+# clean pre-compiled header files
+#
+
+cleanpch:
+\t$(RM) $(OUTPUT_DIR)\*.pch > NUL 2>&1
+
+#
+# clean all dependent libraries built
+#
+
+cleanlib:
+\t${BEGIN}@cd ${dependent_library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) cleanall
+\t${END}@cd $(MODULE_BUILD_DIR)\n'''
+
+    ## Constructor of ModuleMakefile
+    #
+    #   @param  ModuleAutoGen   Object of ModuleAutoGen class
+    #
+    def __init__(self, ModuleAutoGen):
+        BuildFile.__init__(self, ModuleAutoGen)
+        self.PlatformInfo = self._AutoGenObject.PlatformInfo
+
+        self.ResultFileList = []
+        self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]
+
+        self.SourceFileDatabase = {}        # {file type : file path}
+        self.DestFileDatabase = {}          # {file type : file path}
+        self.FileBuildTargetList = []       # [(src, target string)]
+        self.BuildTargetList = []           # [target string]
+        self.PendingBuildTargetList = []    # [FileBuildRule objects]
+        self.CommonFileDependency = []
+
+        self.FileDependency = []
+        self.LibraryBuildCommandList = []
+        self.LibraryFileList = []
+        self.LibraryMakefileList = []
+        self.LibraryBuildDirectoryList = []
+        self.SystemLibraryList = []
+
+    # Compose a dict object containing information used to do replacement in template
+    def _CreateTemplateDict(self):
+        if self._FileType not in self._SEP_:
+            EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type", ExtraData=self._FileType)
+        Separator = self._SEP_[self._FileType]
+
+        # break build if no source files and binary files are found
+        if len(self._AutoGenObject.SourceFileList) == 0 and len(self._AutoGenObject.BinaryFileDict) == 0:
+            EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"
+                            % (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch),
+                            ExtraData=str(self._AutoGenObject))
+        # convert source files and binary files to build target
+        if len(self._AutoGenObject.SourceFileList) > 0:
+            self.ProcessSourceFileList()
+        if len(self._AutoGenObject.BinaryFileDict) > 0:
+            self.ProcessBinaryFileList()
+
+        # convert dependent libaries to build command
+        self.ProcessDependentLibrary()
+        if self._AutoGenObject.Arch == "EBC":
+            # EBC compiler always use "EfiStart" as entry point
+            EntryPoint = "EfiStart"
+        elif self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.Module.ModuleEntryPointList) > 0:
+            # R8 modules use different entry point functions
+            EntryPoint = self._AutoGenObject.Module.ModuleEntryPointList[0]
+        else:
+            # R9 modules always use "_ModuleEntryPoint" as entry point
+            EntryPoint = "_ModuleEntryPoint"
+
+        DefaultToolFlag = self.PlatformInfo.ToolOption.values()
+        # USER_DEFINED modules should take care of tools definitions by its own
+        if self._AutoGenObject.ModuleType == "USER_DEFINED":
+            DefaultToolFlag = ["" for p in DefaultToolFlag]
+
+        if "CC" not in self.PlatformInfo.ToolChainFamily:
+            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [CC] is not supported [%s, %s, %s]" % (self._AutoGenObject.BuildTarget,
+                                    self._AutoGenObject.ToolChain, self._AutoGenObject.Arch))
+        if  "DLINK" not in self.PlatformInfo.ToolChainFamily:
+            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [DLINK] is not supported [%s, %s, %s]" % (self._AutoGenObject.BuildTarget,
+                                    self._AutoGenObject.ToolChain, self._AutoGenObject.Arch))
+
+        if self._AutoGenObject.IsLibrary:
+            if "Static-Library-File" in self.DestFileDatabase:
+                self.ResultFileList = self.DestFileDatabase["Static-Library-File"]
+        elif self._AutoGenObject.ModuleType == "USER_DEFINED":
+            if "Dynamic-Library-File" in self.DestFileDatabase:
+                self.ResultFileList = self.DestFileDatabase["Dynamic-Library-File"]
+        if len(self.ResultFileList) == 0:
+            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Nothing found for build", ExtraData=str(self._AutoGenObject))
+
+        SourceFileMacroNameList = []
+        SourceFileMacroList = [] # macro name = file list
+        for FileType in self.SourceFileDatabase:
+            Macro = "%s_LIST" % FileType.replace("-", "_").upper()
+            SourceFileMacroNameList.append("$(%s)" % Macro)
+            Template = TemplateString()
+            Template.Append("%s = ${BEGIN}${source_file} \\\n\t${END}" % Macro,
+                            {"source_file" : self.SourceFileDatabase[FileType]})
+            SourceFileMacroList.append(str(Template))
+        TargetFileMacroList = []
+        TargetFileMacroNameList = []
+        for FileType in self.DestFileDatabase:
+            Macro = "%s_LIST" % FileType.replace("-", "_").upper()
+            TargetFileMacroNameList.append("$(%s)" % Macro)
+            Template = TemplateString()
+            Template.Append("%s = ${BEGIN}${target_file} \\\n\t${END}" % Macro,
+                            {"target_file" : self.DestFileDatabase[FileType]})
+            TargetFileMacroList.append(str(Template))
+
+        # R8 modules need <BaseName>StrDefs.h for string ID
+        if self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.UnicodeFileList) > 0:
+            AutoGenHeaderFile = os.path.join("$(DEBUG_DIR)", "AutoGen.h")
+            StringHeaderFile = os.path.join("$(DEBUG_DIR)", "%sStrDefs.h" % self._AutoGenObject.Name)
+            CopyAutoGenHeaderFile = ["$(CP) %s %s" % (AutoGenHeaderFile, StringHeaderFile)]
+        else:
+            CopyAutoGenHeaderFile = []
+
+        MakefileName = self._FILE_NAME_[self._FileType]
+        MakefileTemplateDict = {
+            "makefile_header"           : self._FILE_HEADER_[self._FileType],
+            "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
+            "platform_name"             : self.PlatformInfo.Name,
+            "platform_guid"             : self.PlatformInfo.Guid,
+            "platform_version"          : self.PlatformInfo.Version,
+            "platform_relative_directory": self.PlatformInfo.SourceDir,
+            "platform_output_directory" : self.PlatformInfo.OutputDir,
+
+            "module_name"               : self._AutoGenObject.Name,
+            "module_guid"               : self._AutoGenObject.Guid,
+            "module_version"            : self._AutoGenObject.Version,
+            "module_type"               : self._AutoGenObject.ModuleType,
+            "module_file_base_name"     : self._AutoGenObject.FileBase,
+            "module_relative_directory" : self._AutoGenObject.SourceDir,
+
+            "architecture"              : self._AutoGenObject.Arch,
+            "toolchain_tag"             : self._AutoGenObject.ToolChain,
+            "build_target"              : self._AutoGenObject.BuildTarget,
+
+            "platform_build_directory"  : self.PlatformInfo.BuildDir,
+
+            "separator"                 : Separator,
+            "module_tool_flags"         : [self._AutoGenObject.BuildOption[tool] for tool in self.PlatformInfo.ToolPath],
+
+            "tool_code"                 : self.PlatformInfo.ToolPath.keys(),
+            "tool_path"                 : self.PlatformInfo.ToolPath.values(),
+
+            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),
+            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),
+
+            "module_entry_point"        : EntryPoint,
+            "include_path_prefix"       : self._INC_FLAG_[self.PlatformInfo.ToolChainFamily["CC"]],
+            "dlink_output_flag"         : self.PlatformInfo.OutputFlag["DLINK"],
+            "slink_output_flag"         : self.PlatformInfo.OutputFlag["SLINK"],
+            "start_group_flag"          : self._LIB_GROUP_START_[self.PlatformInfo.ToolChainFamily["DLINK"]],
+            "end_group_flag"            : self._LIB_GROUP_END[self.PlatformInfo.ToolChainFamily["DLINK"]],
+            "include_path"              : self._AutoGenObject.IncludePathList,
+            "library_file"              : self.LibraryFileList,
+            "remaining_build_target"    : self.ResultFileList,
+            "system_library"            : self.SystemLibraryList,
+            "common_dependency_file"    : self.CommonFileDependency,
+            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
+            "clean_command"             : self.GetRemoveDirectoryCommand(["$(OUTPUT_DIR)"]),
+            "cleanall_command"          : self.GetRemoveDirectoryCommand(["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]),
+            "dependent_library_build_directory" : self.LibraryBuildDirectoryList,
+            "source_file_macro"         : SourceFileMacroList,
+            "target_file_macro"         : TargetFileMacroList,
+            "source_file_macro_name"    : SourceFileMacroNameList,
+            "target_file_macro_name"    : TargetFileMacroNameList,
+            "file_build_target"         : self.BuildTargetList,
+            "copy_autogen_h"            : CopyAutoGenHeaderFile,
+        }
+
+        return MakefileTemplateDict
+
+    ## Process source files to generate makefile targets and dependencies
+    #
+    #  The intermediate and final targets and dependencies are controlled by
+    #  build rules in $(WORKSPACE)/Conf/build_rule.txt. The dependencies of source
+    #  file are figured out by search included files in the source file.
+    #
+    def ProcessSourceFileList(self):
+        Separator = self._SEP_[self._FileType]
+
+        ForceIncludedFile = []
+        SourceFileList = []
+        ExtraDenpendencies = {}
+
+        if "CC" not in self.PlatformInfo.ToolChainFamily:
+            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No CC tool found",
+                            ExtraData=str(self._AutoGenObject.Module))
+        Family = self.PlatformInfo.ToolChainFamily["CC"]
+        BuildRule = self.PlatformInfo.BuildRule
+
+        CCodeFlag = False
+        FileList = self._AutoGenObject.SourceFileList
+        SourceDir = os.path.join(self._AutoGenObject.WorkspaceDir, self._AutoGenObject.SourceDir)
+        for FileInfo in FileList:
+            F, SrcFileType, SrcFileBuildRule = FileInfo
+            # no rule, no build
+            if SrcFileBuildRule == None:
+                continue
+            if SrcFileType == "C-Code-File":
+                CCodeFlag = True
+            SrcFileName = path.basename(F)
+            SrcFileBase, SrcFileExt = path.splitext(SrcFileName)
+            SrcFileDir = path.dirname(F)
+            if SrcFileDir == "":
+                SrcFileDir = "."
+            else:
+                P = "$(OUTPUT_DIR)" + Separator + SrcFileDir
+                if P not in self.IntermediateDirectoryList:
+                    self.IntermediateDirectoryList.append(P)
+            SrcFileRelativePath = os.path.join(SourceDir, F)
+
+            SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(F, SourceDir, Separator)
+            if SrcFileType not in self.SourceFileDatabase:
+                self.SourceFileDatabase[SrcFileType] = []
+            self.SourceFileDatabase[SrcFileType].append(SrcFile)
+            SourceFileList.append(SrcFileRelativePath)
+            ExtraDenpendencies[SrcFileRelativePath] = ExtraSrcFileList
+
+            BuildTargetTemplate = "${BEGIN}%s : ${deps}\n"\
+                                  "${END}\t%s\n" % (DstFile, "\n\t".join(CommandList))
+            self.FileBuildTargetList.append((SrcFileRelativePath, BuildTargetTemplate))
+
+            while True:
+                # next target
+                DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)
+                if DstFileType == None:
+                    DstFileType = "Unknown-Type-File"
+
+                if DstFileType  in self.SourceFileDatabase:
+                    self.SourceFileDatabase[DstFileType].append(DstFile)
+                else:
+                    if DstFileType not in self.DestFileDatabase:
+                        self.DestFileDatabase[DstFileType] = []
+                    self.DestFileDatabase[DstFileType].append(DstFile)
+
+                if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:
+                    if DstFileBuildRule not in self.PendingBuildTargetList:
+                        self.PendingBuildTargetList.append(DstFileBuildRule)
+                    break
+                elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:
+                    self.ResultFileList.append(DstFile)
+                    break
+
+                SrcFile, ExtraSrcFileList, DstFile, CommandList = DstFileBuildRule.Apply(DstFile, None, Separator)
+                BuildTargetString = "%s : %s %s\n"\
+                                    "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))
+                self.FileBuildTargetList.append((SrcFile, BuildTargetString))
+                SrcFileBuildRule = DstFileBuildRule
+
+        # handle pending targets
+        TempBuildTargetList = []
+        while True:
+            while len(self.PendingBuildTargetList) > 0:
+                SrcFileBuildRule = self.PendingBuildTargetList.pop()
+                SrcFileList = []
+                for FileType in SrcFileBuildRule.SourceFileType:
+                    if FileType not in self.SourceFileDatabase:
+                        if FileType not in self.DestFileDatabase:
+                            continue
+                        else:
+                            SrcFileList.extend(self.DestFileDatabase[FileType])
+                    else:
+                        SrcFileList.extend(self.SourceFileDatabase[FileType])
+                SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(SrcFileList, None, Separator)
+                BuildTargetString = "%s : %s %s\n"\
+                                    "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))
+                self.FileBuildTargetList.append((SrcFile, BuildTargetString))
+
+                # try to find next target
+                while True:
+                    DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)
+                    if DstFileType == None:
+                        DstFileType = "Unknown-Type-File"
+
+                    if DstFileType  in self.SourceFileDatabase:
+                        self.SourceFileDatabase[DstFileType].append(DstFile)
+                    else:
+                        if DstFileType not in self.DestFileDatabase:
+                            self.DestFileDatabase[DstFileType] = []
+                        self.DestFileDatabase[DstFileType].append(DstFile)
+
+                    if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:
+                        TempBuildTargetList.append(DstFileBuildRule)
+                        break
+                    elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:
+                        self.ResultFileList.append(DstFile)
+                        break
+
+                    SrcFile, ExtraSrcFileList, DstFile, CommandList = DstFileBuildRule.Apply(DstFile, None, Separator)
+                    BuildTargetString = "%s : %s %s\n"\
+                                        "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))
+                    self.FileBuildTargetList.append((SrcFile, BuildTargetString))
+                    SrcFileBuildRule = DstFileBuildRule
+            if len(TempBuildTargetList) == 0:
+                break
+            self.PendingBuildTargetList = TempBuildTargetList
+
+        # Build AutoGen files only if we have C source files
+        if CCodeFlag == True:
+            for F in self._AutoGenObject.AutoGenFileList:
+                SrcFileName = path.basename(F)
+                SrcFileBase, SrcFileExt = path.splitext(SrcFileName)
+                SrcFileDir = path.dirname(F)
+                if SrcFileDir == "":
+                    SrcFileDir = "."
+                else:
+                    P = "$(DEBUG_DIR)" + Separator + SrcFileDir
+                    if P not in self.IntermediateDirectoryList:
+                        self.IntermediateDirectoryList.append(P)
+
+                SrcFileRelativePath = os.path.join(self._AutoGenObject.DebugDir, F)
+
+                SrcFileType, SrcFileBuildRule = BuildRule.Get(SrcFileExt, Family)
+                if SrcFileType != None and SrcFileType == "C-Header-File":
+                    ForceIncludedFile.append(SrcFileRelativePath)
+                if SrcFileBuildRule == None or SrcFileBuildRule.CommandList == []:
+                    continue
+
+                SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(F, self._AutoGenObject.DebugDir, Separator)
+
+                if SrcFileType not in self.SourceFileDatabase:
+                    self.SourceFileDatabase[SrcFileType] = []
+                self.SourceFileDatabase[SrcFileType].append(SrcFile)
+                SourceFileList.append(SrcFileRelativePath)
+                ExtraDenpendencies[SrcFileRelativePath] = ExtraSrcFileList
+
+                BuildTargetTemplate = "${BEGIN}%s : ${deps}\n"\
+                                      "${END}\t%s\n" % (DstFile, "\n\t".join(CommandList))
+                self.FileBuildTargetList.append((SrcFileRelativePath, BuildTargetTemplate))
+
+                while True:
+                    # next target
+                    DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)
+                    if DstFileType == None:
+                        DstFileType = "Unknown-Type-File"
+
+                    if DstFileType  in self.SourceFileDatabase:
+                        self.SourceFileDatabase[DstFileType].append(DstFile)
+                    else:
+                        if DstFileType not in self.DestFileDatabase:
+                            self.DestFileDatabase[DstFileType] = []
+                        self.DestFileDatabase[DstFileType].append(DstFile)
+
+                    if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:
+                        if DstFileBuildRule not in self.PendingBuildTargetList:
+                            self.PendingBuildTargetList.append(DstFileBuildRule)
+                        break
+                    elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:
+                        self.ResultFileList.append(DstFile)
+                        break
+
+                    SrcFile, ExtraSrcFileList, DstFile, CommandList = DstFileBuildRule.Apply(DstFile, None, Separator)
+                    BuildTargetString = "%s : %s %s\n"\
+                                        "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))
+                    self.FileBuildTargetList.append((SrcFile, BuildTargetString))
+                    SrcFileBuildRule = DstFileBuildRule
+
+        #
+        # Search dependency file list for each source file
+        #
+        self.FileDependency = self.GetFileDependency(SourceFileList, ForceIncludedFile, self._AutoGenObject.IncludePathList)
+        DepSet = None
+        for File in self.FileDependency:
+            if self.FileDependency[File] == []:
+                self.FileDependency[File] = ['$(FORCE_REBUILD)']
+            elif File in ExtraDenpendencies:
+                self.FileDependency[File] += ExtraDenpendencies[File]
+            # skip non-C files
+            if (not File.endswith(".c") and not File.endswith(".C")) or File.endswith("AutoGen.c"):
+                continue
+            elif DepSet == None:
+                DepSet = set(self.FileDependency[File])
+            else:
+                DepSet &= set(self.FileDependency[File])
+        # in case nothing in SourceFileList
+        if DepSet == None:
+            DepSet = set()
+        #
+        # Extract comman files list in the dependency files
+        #
+        self.CommonFileDependency = list(DepSet)
+        for File in self.FileDependency:
+            # skip non-C files
+            if (not File.endswith(".c") and not File.endswith(".C")) or File.endswith("AutoGen.c"):
+                continue
+            NewDepSet = set(self.FileDependency[File])
+            NewDepSet -= DepSet
+            self.FileDependency[File] = ["$(COMMON_DEPS)"] + list(NewDepSet)
+
+        # EdkLogger.verbose("Files to be built in %s :\n\t %s\n" % (str(self._AutoGenObject), "\n\t".join(self.FileDependency.keys())))
+        for File, TargetTemplate in self.FileBuildTargetList:
+            if File not in self.FileDependency:
+                self.BuildTargetList.append(TargetTemplate)
+                continue
+            Template = TemplateString()
+            Template.Append(TargetTemplate, {"deps" : self.FileDependency[File]})
+            self.BuildTargetList.append(str(Template))
+
+
+    ## Process binary files to generate makefile targets and dependencies
+    #
+    # All binary files are just copied to $(OUTPUT_DIR)
+    #
+    def ProcessBinaryFileList(self):
+        BinaryFiles = self._AutoGenObject.BinaryFileDict
+        BuildTargetString = "%(dst)s : %(src)s\n"\
+                            "\t$(CP) %(src)s %(dst)s\n"
+        for FileType in BinaryFiles:
+            if FileType not in self.DestFileDatabase:
+                self.DestFileDatabase[FileType] = []
+            for F in BinaryFiles[FileType]:
+                Src = os.path.join("$(MODULE_DIR)", F)
+                FileName = os.path.basename(F)
+                Dst = os.path.join("$(OUTPUT_DIR)", FileName)
+                self.DestFileDatabase[FileType].append(Dst)
+                self.ResultFileList.append(Dst)
+                self.BuildTargetList.append(BuildTargetString % {"dst":Dst, "src":Src})
+
+    ## For creating makefile targets for dependent libraries
+    def ProcessDependentLibrary(self):
+        for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
+            self.LibraryBuildDirectoryList.append(LibraryAutoGen.BuildDir)
+            self.LibraryFileList.append(os.path.join(LibraryAutoGen.OutputDir, LibraryAutoGen.Name + ".lib"))
+
+    ## Return a list containing source file's dependencies
+    #
+    #   @param      FileList        The list of source files
+    #   @param      ForceInculeList The list of files which will be included forcely
+    #   @param      SearchPathList  The list of search path
+    #
+    #   @retval     dict            The mapping between source file path and its dependencies
+    #
+    def GetFileDependency(self, FileList, ForceInculeList, SearchPathList):
+        Dependency = {}
+        for F in FileList:
+            Dependency[F] = self.GetDependencyList(F, ForceInculeList, SearchPathList)
+        return Dependency
+
+    ## Find dependencies for one source file
+    #
+    #  By searching recursively "#include" directive in file, find out all the
+    #  files needed by given source file. The dependecies will be only searched
+    #  in given search path list.
+    #
+    #   @param      File            The source file
+    #   @param      ForceInculeList The list of files which will be included forcely
+    #   @param      SearchPathList  The list of search path
+    #
+    #   @retval     list            The list of files the given source file depends on
+    #
+    def GetDependencyList(self, File, ForceList, SearchPathList):
+        EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File)
+        EdkLogger.debug(EdkLogger.DEBUG_0, "Including %s" % " ".join(ForceList))
+        FileStack = [File] + ForceList
+        DependencySet = set()
+        MacroUsedByIncludedFile = False
+
+        if self._AutoGenObject.Arch not in gDependencyDatabase:
+            gDependencyDatabase[self._AutoGenObject.Arch] = {}
+        DepDb = gDependencyDatabase[self._AutoGenObject.Arch]
+        while len(FileStack) > 0:
+            EdkLogger.debug(EdkLogger.DEBUG_0, "Stack %s" % "\n\t".join(FileStack))
+            F = FileStack.pop()
+
+            CurrentFileDependencyList = []
+            if F in DepDb and not IsChanged(F):
+                CurrentFileDependencyList = DepDb[F]
+                for Dep in CurrentFileDependencyList:
+                    if Dep not in FileStack and Dep not in DependencySet:
+                        FileStack.append(Dep)
+            else:
+                try:
+                    Fd = open(F, 'r')
+                except:
+                    EdkLogger.error("AutoGen", FILE_OPEN_FAILURE, ExtraData=F)
+
+                FileContent = Fd.read()
+                Fd.close()
+                if len(FileContent) == 0:
+                    continue
+
+                if FileContent[0] == 0xff or FileContent[0] == 0xfe:
+                    FileContent = unicode(FileContent, "utf-16")
+                IncludedFileList = gIncludePattern.findall(FileContent)
+
+                CurrentFilePath = os.path.dirname(F)
+                for Inc in IncludedFileList:
+                    # if there's macro used to reference header file, expand it
+                    HeaderList = gMacroPattern.findall(Inc)
+                    if len(HeaderList) == 1 and len(HeaderList[0]) == 2:
+                        HeaderType = HeaderList[0][0]
+                        HeaderKey = HeaderList[0][1]
+                        if HeaderType in gIncludeMacroConversion:
+                            Inc = gIncludeMacroConversion[HeaderType] % {"HeaderKey" : HeaderKey}
+                        else:
+                            # not known macro used in #include
+                            MacroUsedByIncludedFile = True
+                            continue
+                    Inc = os.path.normpath(Inc)
+                    for SearchPath in [CurrentFilePath] + SearchPathList:
+                        FilePath = os.path.join(SearchPath, Inc)
+                        if not os.path.exists(FilePath) or FilePath in CurrentFileDependencyList:
+                            continue
+                        CurrentFileDependencyList.append(FilePath)
+                        if FilePath not in FileStack and FilePath not in DependencySet:
+                            FileStack.append(FilePath)
+                        break
+                    else:
+                        EdkLogger.verbose("%s included by %s was not found in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList)))
+
+                if not MacroUsedByIncludedFile:
+                    if F == File:
+                        CurrentFileDependencyList += ForceList
+                    #
+                    # Don't keep the file in cache if it uses macro in included file.
+                    # So it will be scanned again if another file includes this file.
+                    #
+                    DepDb[F] = CurrentFileDependencyList
+            DependencySet.update(CurrentFileDependencyList)
+
+        #
+        # If there's macro used in included file, always build the file by
+        # returning a empty dependency
+        #
+        if MacroUsedByIncludedFile:
+            DependencyList = []
+        else:
+            DependencyList = list(DependencySet)  # remove duplicate ones
+            DependencyList.append(File)
+
+        return DependencyList
+
+    _TemplateDict = property(_CreateTemplateDict)
+
+## CustomMakefile class
+#
+#  This class encapsules makefie and its generation for module. It uses template to generate
+#  the content of makefile. The content of makefile will be got from ModuleAutoGen object.
+#
+class CustomMakefile(BuildFile):
+    ## template used to generate the makefile for module with custom makefile
+    _TEMPLATE_ = '''\
+${makefile_header}
+
+#
+# Platform Macro Definition
+#
+PLATFORM_NAME = ${platform_name}
+PLATFORM_GUID = ${platform_guid}
+PLATFORM_VERSION = ${platform_version}
+PLATFORM_RELATIVE_DIR = ${platform_relative_directory}
+PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
+PLATFORM_OUTPUT_DIR = ${platform_output_directory}
+
+#
+# Module Macro Definition
+#
+MODULE_NAME = ${module_name}
+MODULE_GUID = ${module_guid}
+MODULE_VERSION = ${module_version}
+MODULE_TYPE = ${module_type}
+MODULE_FILE_BASE_NAME = ${module_file_base_name}
+BASE_NAME = $(MODULE_NAME)
+MODULE_RELATIVE_DIR = ${module_relative_directory}
+MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
+
+#
+# Build Configuration Macro Definition
+#
+ARCH = ${architecture}
+TOOLCHAIN_TAG = ${toolchain_tag}
+TARGET = ${build_target}
+
+#
+# Build Directory Macro Definition
+#
+# PLATFORM_BUILD_DIR = ${platform_build_directory}
+BUILD_DIR = ${platform_build_directory}
+BIN_DIR = $(BUILD_DIR)${separator}${architecture}
+LIB_DIR = $(BIN_DIR)
+MODULE_BUILD_DIR = $(BUILD_DIR)${separator}${architecture}${separator}${module_relative_directory}${separator}${module_file_base_name}
+OUTPUT_DIR = $(MODULE_BUILD_DIR)${separator}OUTPUT
+DEBUG_DIR = $(MODULE_BUILD_DIR)${separator}DEBUG
+DEST_DIR_OUTPUT = $(OUTPUT_DIR)
+DEST_DIR_DEBUG = $(DEBUG_DIR)
+
+#
+# Tools Flag Macro (from platform/module description file, tools_def.txt)
+#
+${BEGIN}${tool_code}_FLAGS = ${module_tool_flags}
+${END}
+
+#
+# Tools Path Macro
+#
+${BEGIN}${tool_code} = ${tool_path}
+${END}
+
+MAKE_FILE = ${makefile_path}
+
+#
+# Shell Command Macro
+#
+${BEGIN}${shell_command_code} = ${shell_command}
+${END}
+
+${custom_makefile_content}
+
+#
+# Target used when called from platform makefile, which will bypass the build of dependent libraries
+#
+
+pbuild: init all
+
+
+#
+# ModuleTarget
+#
+
+mbuild: init all
+
+
+#
+# Initialization target: print build information and create necessary directories
+#
+init:
+\t-@echo Building ... $(MODULE_NAME) [$(ARCH)]
+${BEGIN}\t-@${create_directory_command}\n${END}\
+
+'''
+    ## Constructor of CustomMakefile
+    #
+    #   @param  ModuleAutoGen   Object of ModuleAutoGen class
+    #
+    def __init__(self, ModuleAutoGen):
+        BuildFile.__init__(self, ModuleAutoGen)
+        self.PlatformInfo = self._AutoGenObject.PlatformInfo
+        self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]
+
+    # Compose a dict object containing information used to do replacement in template
+    def _CreateTemplateDict(self):
+        Separator = self._SEP_[self._FileType]
+        try:
+            if self._FileType not in self._AutoGenObject.CustomMakefile:
+                EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,
+                                ExtraData=str(self._AutoGenObject))
+            MakefilePath = os.path.join(
+                                    self._AutoGenObject.WorkspaceDir,
+                                    self._AutoGenObject.CustomMakefile[self._FileType]
+                                    )
+            CustomMakefile = open(MakefilePath, 'r').read()
+        except:
+            EdkLogger.error('build', FILE_OPEN_FAILURE, ExtraData=self._AutoGenObject.CustomMakefile[self._FileType])
+
+        MakefileName = self._FILE_NAME_[self._FileType]
+        MakefileTemplateDict = {
+            "makefile_header"           : self._FILE_HEADER_[self._FileType],
+            "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
+            "platform_name"             : self.PlatformInfo.Name,
+            "platform_guid"             : self.PlatformInfo.Guid,
+            "platform_version"          : self.PlatformInfo.Version,
+            "platform_relative_directory": self.PlatformInfo.SourceDir,
+            "platform_output_directory" : self.PlatformInfo.OutputDir,
+
+            "module_name"               : self._AutoGenObject.Name,
+            "module_guid"               : self._AutoGenObject.Guid,
+            "module_version"            : self._AutoGenObject.Version,
+            "module_type"               : self._AutoGenObject.ModuleType,
+            "module_file_base_name"     : self._AutoGenObject.FileBase,
+            "module_relative_directory" : self._AutoGenObject.SourceDir,
+
+            "architecture"              : self._AutoGenObject.Arch,
+            "toolchain_tag"             : self._AutoGenObject.ToolChain,
+            "build_target"              : self._AutoGenObject.BuildTarget,
+
+            "platform_build_directory"  : self.PlatformInfo.BuildDir,
+
+            "separator"                 : Separator,
+            "module_tool_flags"         : [self._AutoGenObject.BuildOption[tool] for tool in self.PlatformInfo.ToolPath],
+
+            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),
+            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),
+
+            "tool_code"                 : self.PlatformInfo.ToolPath.keys(),
+            "tool_path"                 : self.PlatformInfo.ToolPath.values(),
+
+            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
+            "custom_makefile_content"   : CustomMakefile
+        }
+
+        return MakefileTemplateDict
+
+    _TemplateDict = property(_CreateTemplateDict)
+
+## PlatformMakefile class
+#
+#  This class encapsules makefie and its generation for platform. It uses
+# template to generate the content of makefile. The content of makefile will be
+# got from PlatformAutoGen object.
+#
+class PlatformMakefile(BuildFile):
+    ## template used to generate the makefile for platform
+    _TEMPLATE_ = '''\
+${makefile_header}
+
+#
+# Platform Macro Definition
+#
+PLATFORM_NAME = ${platform_name}
+PLATFORM_GUID = ${platform_guid}
+PLATFORM_VERSION = ${platform_version}
+PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
+PLATFORM_OUTPUT_DIR = ${platform_output_directory}
+
+#
+# Build Configuration Macro Definition
+#
+TOOLCHAIN_TAG = ${toolchain_tag}
+TARGET = ${build_target}
+
+#
+# Build Directory Macro Definition
+#
+BUILD_DIR = ${platform_build_directory}
+FV_DIR = ${platform_build_directory}${separator}FV
+
+#
+# Shell Command Macro
+#
+${BEGIN}${shell_command_code} = ${shell_command}
+${END}
+
+MAKE = ${make_path}
+MAKE_FLAGS = ${make_flag}
+MAKE_FILE = ${makefile_path}
+
+#
+# Default target
+#
+all: init build_libraries build_modules
+
+#
+# Initialization target: print build information and create necessary directories
+#
+init:
+\t-@echo Building ... $(PLATFORM_NAME) [${build_architecture_list}]
+\t${BEGIN}-@${create_directory_command}
+\t${END}
+#
+# library build target
+#
+libraries: init build_libraries
+
+#
+# module build target
+#
+modules: init build_libraries build_modules
+
+#
+# Build all libraries:
+#
+build_libraries:
+${BEGIN}\t@cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) pbuild
+${END}\t@cd $(BUILD_DIR)
+
+#
+# Build all modules:
+#
+build_modules:
+${BEGIN}\t@cd ${module_build_directory} && "$(MAKE)" $(MAKE_FLAGS) pbuild
+${END}\t@cd $(BUILD_DIR)
+
+#
+# Clean intermediate files
+#
+clean:
+\t${BEGIN}@cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) clean
+\t${END}${BEGIN}@cd ${module_build_directory} && "$(MAKE)" $(MAKE_FLAGS) clean
+\t${END}@cd $(BUILD_DIR)
+
+#
+# Clean all generated files except to makefile
+#
+cleanall:
+${BEGIN}\t${cleanall_command}
+${END}
+
+#
+# Clean all library files
+#
+cleanlib:
+\t${BEGIN}@cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) cleanall
+\t${END}@cd $(BUILD_DIR)\n
+'''
+
+    ## Constructor of PlatformMakefile
+    #
+    #   @param  ModuleAutoGen   Object of PlatformAutoGen class
+    #
+    def __init__(self, PlatformAutoGen):
+        BuildFile.__init__(self, PlatformAutoGen)
+        self.ModuleBuildCommandList = []
+        self.ModuleMakefileList = []
+        self.IntermediateDirectoryList = []
+        self.ModuleBuildDirectoryList = []
+        self.LibraryBuildDirectoryList = []
+
+    # Compose a dict object containing information used to do replacement in template
+    def _CreateTemplateDict(self):
+        Separator = self._SEP_[self._FileType]
+
+        PlatformInfo = self._AutoGenObject
+        if "MAKE" not in PlatformInfo.ToolPath:
+            EdkLogger.error("GenMake", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!")
+
+        self.IntermediateDirectoryList = ["$(BUILD_DIR)"]
+        self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()
+        self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()
+
+        MakefileName = self._FILE_NAME_[self._FileType]
+        MakefileTemplateDict = {
+            "makefile_header"           : self._FILE_HEADER_[self._FileType],
+            "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),
+            "platform_name"             : PlatformInfo.Name,
+            "platform_guid"             : PlatformInfo.Guid,
+            "platform_version"          : PlatformInfo.Version,
+            "platform_relative_directory": PlatformInfo.SourceDir,
+            "platform_output_directory" : PlatformInfo.OutputDir,
+            "platform_build_directory"  : PlatformInfo.BuildDir,
+
+            "toolchain_tag"             : PlatformInfo.ToolChain,
+            "build_target"              : PlatformInfo.BuildTarget,
+            "make_path"                 : PlatformInfo.ToolPath["MAKE"],
+            "make_flag"                 : PlatformInfo.ToolOption["MAKE"],
+            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),
+            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),
+            "build_architecture_list"   : self._AutoGenObject.Arch,
+            "architecture"              : self._AutoGenObject.Arch,
+            "separator"                 : Separator,
+            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
+            "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),
+            "library_build_directory"   : self.LibraryBuildDirectoryList,
+            "module_build_directory"    : self.ModuleBuildDirectoryList,
+            "active_platform"           : PlatformInfo.WorkspaceDir + Separator + str(PlatformInfo),
+        }
+
+        return MakefileTemplateDict
+
+    ## Get the root directory list for intermediate files of all modules build
+    #
+    #   @retval     list    The list of directory
+    #
+    def GetModuleBuildDirectoryList(self):
+        DirList = []
+        for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:
+            DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
+        return DirList
+
+    ## Get the root directory list for intermediate files of all libraries build
+    #
+    #   @retval     list    The list of directory
+    #
+    def GetLibraryBuildDirectoryList(self):
+        DirList = []
+        for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
+            DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
+        return DirList
+
+    _TemplateDict = property(_CreateTemplateDict)
+
+## TopLevelMakefile class
+#
+#  This class encapsules makefie and its generation for entrance makefile. It
+# uses template to generate the content of makefile. The content of makefile
+# will be got from WorkspaceAutoGen object.
+#
+class TopLevelMakefile(BuildFile):
+    ## template used to generate toplevel makefile
+    _TEMPLATE_ = '''\
+${makefile_header}
+
+#
+# Platform Macro Definition
+#
+PLATFORM_NAME = ${platform_name}
+PLATFORM_GUID = ${platform_guid}
+PLATFORM_VERSION = ${platform_version}
+
+#
+# Build Configuration Macro Definition
+#
+TOOLCHAIN_TAG = ${toolchain_tag}
+TARGET = ${build_target}
+
+#
+# Build Directory Macro Definition
+#
+BUILD_DIR = ${platform_build_directory}
+FV_DIR = ${platform_build_directory}${separator}FV
+
+#
+# Shell Command Macro
+#
+${BEGIN}${shell_command_code} = ${shell_command}
+${END}
+
+MAKE = ${make_path}
+MAKE_FLAGS = ${make_flag}
+MAKE_FILE = ${makefile_path}
+
+#
+# Default target
+#
+all: modules fds
+
+#
+# Initialization target: print build information and create necessary directories
+#
+init:
+\t-@echo Building ... $(PLATFORM_NAME) [${build_architecture_list}]
+\t${BEGIN}-@${create_directory_command}
+\t${END}
+#
+# library build target
+#
+libraries: init
+${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) libraries
+${END}\t@cd $(BUILD_DIR)
+
+#
+# module build target
+#
+modules: init
+${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) modules
+${END}\t@cd $(BUILD_DIR)
+
+#
+# Flash Device Image Target
+#
+fds: init
+\t-@cd $(FV_DIR)
+${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN_TAG) -b $(TARGET) -p ${active_platform} -a ${build_architecture_list} ${log_level}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -y ${macro} ${END}
+
+#
+# run command for emulator platform only
+#
+run:
+\tcd $(BUILD_DIR)${separator}IA32
+\tSecMain
+\tcd $(BUILD_DIR)
+
+#
+# Clean intermediate files
+#
+clean:
+${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) clean
+${END}\t@cd $(BUILD_DIR)
+
+#
+# Clean all generated files except to makefile
+#
+cleanall:
+${BEGIN}\t${cleanall_command}
+${END}
+
+#
+# Clean all library files
+#
+cleanlib:
+${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) cleanlib
+${END}\t@cd $(BUILD_DIR)\n
+'''
+
+    ## Constructor of TopLevelMakefile
+    #
+    #   @param  Workspace   Object of WorkspaceAutoGen class
+    #
+    def __init__(self, Workspace):
+        BuildFile.__init__(self, Workspace)
+        self.IntermediateDirectoryList = []
+
+    # Compose a dict object containing information used to do replacement in template
+    def _CreateTemplateDict(self):
+        Separator = self._SEP_[self._FileType]
+
+        # any platform autogen object is ok because we just need common information
+        PlatformInfo = self._AutoGenObject
+
+        if "MAKE" not in PlatformInfo.ToolPath:
+            EdkLogger.error("GenMake", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!")
+
+        for Arch in PlatformInfo.ArchList:
+            self.IntermediateDirectoryList.append(Separator.join(["$(BUILD_DIR)", Arch]))
+        self.IntermediateDirectoryList.append("$(FV_DIR)")
+
+        # TRICK: for not generating GenFds call in makefile if no FDF file
+        MacroList = []
+        if PlatformInfo.FdfFile != None and PlatformInfo.FdfFile != "":
+            FdfFileList = [PlatformInfo.FdfFile]
+            # macros passed to GenFds
+            for MacroName in GlobalData.gGlobalDefines:
+                MacroList.append('"%s=%s"' % (MacroName, GlobalData.gGlobalDefines[MacroName]))
+        else:
+            FdfFileList = []
+
+        # pass log level to external program called in makefile, currently GenFds.exe
+        LogLevel = EdkLogger.GetLevel()
+        if LogLevel == EdkLogger.VERBOSE:
+            LogOption = "-v"
+        elif LogLevel <= EdkLogger.DEBUG_9:
+            LogOption = "-d %d" % (LogLevel - 1)
+        elif LogLevel == EdkLogger.QUIET:
+            LogOption = "-q"
+        else:
+            LogOption = ""
+
+        MakefileName = self._FILE_NAME_[self._FileType]
+        MakefileTemplateDict = {
+            "makefile_header"           : self._FILE_HEADER_[self._FileType],
+            "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),
+            "platform_name"             : PlatformInfo.Name,
+            "platform_guid"             : PlatformInfo.Guid,
+            "platform_version"          : PlatformInfo.Version,
+            "platform_build_directory"  : PlatformInfo.BuildDir,
+
+            "toolchain_tag"             : PlatformInfo.ToolChain,
+            "build_target"              : PlatformInfo.BuildTarget,
+            "make_path"                 : PlatformInfo.ToolPath["MAKE"],
+            "make_flag"                 : PlatformInfo.ToolOption["MAKE"],
+            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),
+            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),
+            'arch'                      : list(PlatformInfo.ArchList),
+            "build_architecture_list"   : ','.join(PlatformInfo.ArchList),
+            "separator"                 : Separator,
+            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
+            "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),
+            "fdf_file"                  : FdfFileList,
+            "active_platform"           : PlatformInfo.WorkspaceDir + Separator + str(PlatformInfo),
+            "fd"                        : PlatformInfo.FdTargetList,
+            "fv"                        : PlatformInfo.FvTargetList,
+            "log_level"                 : LogOption,
+            "macro"                     : MacroList,
+        }
+
+        return MakefileTemplateDict
+
+    ## Get the root directory list for intermediate files of all modules build
+    #
+    #   @retval     list    The list of directory
+    #
+    def GetModuleBuildDirectoryList(self):
+        DirList = []
+        for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:
+            DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
+        return DirList
+
+    ## Get the root directory list for intermediate files of all libraries build
+    #
+    #   @retval     list    The list of directory
+    #
+    def GetLibraryBuildDirectoryList(self):
+        DirList = []
+        for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
+            DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
+        return DirList
+
+    _TemplateDict = property(_CreateTemplateDict)
+
+# This acts like the main() function for the script, unless it is 'import'ed into another script.
+if __name__ == '__main__':
+    pass
+
index c0ba373..8fc8d33 100755 (executable)
-## @file\r
-# Common routines used by all tools\r
-#\r
-# Copyright (c) 2007, Intel Corporation\r
-# All rights reserved. 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
-#\r
-\r
-##\r
-# Import Modules\r
-#\r
-import os\r
-import sys\r
-import string\r
-import thread\r
-import threading\r
-import time\r
-import re\r
-import cPickle\r
-from UserDict import IterableUserDict\r
-from UserList import UserList\r
-\r
-from Common import EdkLogger as EdkLogger\r
-from BuildToolError import *\r
-\r
-## Regular expression used to find out place holders in string template\r
-gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE|re.UNICODE)\r
-\r
-## Dictionary used to store file time stamp for quick re-access\r
-gFileTimeStampCache = {}    # {file path : file time stamp}\r
-\r
-## Dictionary used to store dependencies of files\r
-gDependencyDatabase = {}    # arch : {file path : [dependent files list]}\r
-\r
-## callback routine for processing variable option\r
-#\r
-# This function can be used to process variable number of option values. The\r
-# typical usage of it is specify architecure list on command line.\r
-# (e.g. <tool> -a IA32 X64 IPF)\r
-#\r
-# @param  Option        Standard callback function parameter\r
-# @param  OptionString  Standard callback function parameter\r
-# @param  Value         Standard callback function parameter\r
-# @param  Parser        Standard callback function parameter\r
-#\r
-# @retval\r
-#\r
-def ProcessVariableArgument(Option, OptionString, Value, Parser):\r
-    assert Value is None\r
-    Value = []\r
-    RawArgs = Parser.rargs\r
-    while RawArgs:\r
-        Arg = RawArgs[0]\r
-        if (Arg[:2] == "--" and len(Arg) > 2) or \\r
-           (Arg[:1] == "-" and len(Arg) > 1 and Arg[1] != "-"):\r
-            break\r
-        Value.append(Arg)\r
-        del RawArgs[0]\r
-    setattr(Parser.values, Option.dest, Value)\r
-\r
-## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C structure style\r
-#\r
-#   @param      Guid    The GUID string\r
-#\r
-#   @retval     string  The GUID string in C structure style\r
-#\r
-def GuidStringToGuidStructureString(Guid):\r
-    GuidList = Guid.split('-')\r
-    Result = '{'\r
-    for Index in range(0,3,1):\r
-        Result = Result + '0x' + GuidList[Index] + ', '\r
-    Result = Result + '{0x' + GuidList[3][0:2] + ', 0x' + GuidList[3][2:4]\r
-    for Index in range(0,12,2):\r
-        Result = Result + ', 0x' + GuidList[4][Index:Index+2]\r
-    Result += '}}'\r
-    return Result\r
-\r
-## Convert GUID string in C structure style to xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\r
-#\r
-#   @param      GuidValue   The GUID value in C structure format\r
-#\r
-#   @retval     string      The GUID value in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format\r
-#\r
-def GuidStructureStringToGuidString(GuidValue):\r
-    guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "").replace(";", "")\r
-    guidValueList = guidValueString.split(",")\r
-    if len(guidValueList) != 11:\r
-        return ''\r
-        #EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue)\r
-    try:\r
-        return "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" % (\r
-                int(guidValueList[0], 16),\r
-                int(guidValueList[1], 16),\r
-                int(guidValueList[2], 16),\r
-                int(guidValueList[3], 16),\r
-                int(guidValueList[4], 16),\r
-                int(guidValueList[5], 16),\r
-                int(guidValueList[6], 16),\r
-                int(guidValueList[7], 16),\r
-                int(guidValueList[8], 16),\r
-                int(guidValueList[9], 16),\r
-                int(guidValueList[10], 16)\r
-                )\r
-    except:\r
-        return ''\r
-\r
-## Convert GUID string in C structure style to xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx\r
-#\r
-#   @param      GuidValue   The GUID value in C structure format\r
-#\r
-#   @retval     string      The GUID value in xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx format\r
-#\r
-def GuidStructureStringToGuidValueName(GuidValue):\r
-    guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "")\r
-    guidValueList = guidValueString.split(",")\r
-    if len(guidValueList) != 11:\r
-        EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue)\r
-    return "%08x_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x" % (\r
-            int(guidValueList[0], 16),\r
-            int(guidValueList[1], 16),\r
-            int(guidValueList[2], 16),\r
-            int(guidValueList[3], 16),\r
-            int(guidValueList[4], 16),\r
-            int(guidValueList[5], 16),\r
-            int(guidValueList[6], 16),\r
-            int(guidValueList[7], 16),\r
-            int(guidValueList[8], 16),\r
-            int(guidValueList[9], 16),\r
-            int(guidValueList[10], 16)\r
-            )\r
-\r
-## Create directories\r
-#\r
-#   @param      Directory   The directory name\r
-#\r
-def CreateDirectory(Directory):\r
-    if Directory == None or Directory.strip() == "":\r
-        return True\r
-    try:\r
-        if not os.access(Directory, os.F_OK):\r
-            os.makedirs(Directory)\r
-    except:\r
-        return False\r
-    return True\r
-\r
-## Check if given file is changed or not\r
-#\r
-#  This method is used to check if a file is changed or not between two build\r
-#  actions. It makes use a cache to store files timestamp.\r
-#\r
-#   @param      File    The path of file\r
-#\r
-#   @retval     True    If the given file is changed, doesn't exist, or can't be\r
-#                       found in timestamp cache\r
-#   @retval     False   If the given file is changed\r
-#\r
-def IsChanged(File):\r
-    if not os.path.exists(File):\r
-        return True\r
-\r
-    FileState = os.stat(File)\r
-    TimeStamp = FileState[-2]\r
-\r
-    if File in gFileTimeStampCache and TimeStamp <= gFileTimeStampCache[File]:\r
-        FileChanged = False\r
-    else:\r
-        FileChanged = True\r
-        gFileTimeStampCache[File] = TimeStamp\r
-\r
-    return FileChanged\r
-\r
-## Store content in file\r
-#\r
-#  This method is used to save file only when its content is changed. This is\r
-#  quite useful for "make" system to decide what will be re-built and what won't.\r
-#\r
-#   @param      File            The path of file\r
-#   @param      Content         The new content of the file\r
-#   @param      IsBinaryFile    The flag indicating if the file is binary file or not\r
-#\r
-#   @retval     True            If the file content is changed and the file is renewed\r
-#   @retval     False           If the file content is the same\r
-#\r
-def SaveFileOnChange(File, Content, IsBinaryFile=True):\r
-    if IsBinaryFile:\r
-        BinaryFlag = 'b'\r
-    else:\r
-        BinaryFlag = ''\r
-    Fd = None\r
-    if os.path.exists(File):\r
-        try:\r
-            Fd = open(File, "r"+BinaryFlag)\r
-        except:\r
-            EdkLogger.error(None, FILE_OPEN_FAILURE, ExtraData=File)\r
-        FileSize = os.fstat(Fd.fileno()).st_size\r
-        if len(Content) == FileSize and Content == Fd.read():\r
-            Fd.close()\r
-            return False\r
-        Fd.close()\r
-        # os.remove(File) # seems creating new file is faster than overwriting old one\r
-    CreateDirectory(os.path.dirname(File))\r
-    try:\r
-        Fd = open(File, "w"+BinaryFlag)\r
-    except:\r
-        EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData=File)\r
-    Fd.write(Content)\r
-    Fd.close()\r
-    return True\r
-\r
-## Make a Python object persistent on file system\r
-#\r
-#   @param      Data    The object to be stored in file\r
-#   @param      File    The path of file to store the object\r
-#\r
-def DataDump(Data, File):\r
-    Fd = None\r
-    try:\r
-        Fd = open(File, 'wb')\r
-        cPickle.dump(Data, Fd, cPickle.HIGHEST_PROTOCOL)\r
-    except:\r
-        EdkLogger.error("", FILE_OPEN_FAILURE, ExtraData=File, RaiseError=False)\r
-    finally:\r
-        if Fd != None:\r
-            Fd.close()\r
-\r
-## Restore a Python object from a file\r
-#\r
-#   @param      File    The path of file stored the object\r
-#\r
-#   @retval     object  A python object\r
-#   @retval     None    If failure in file operation\r
-#\r
-def DataRestore(File):\r
-    Data = None\r
-    Fd = None\r
-    try:\r
-        Fd = open(File, 'rb')\r
-        Data = cPickle.load(Fd)\r
-    except Exception, e:\r
-        EdkLogger.verbose("Failed to load [%s]\n\t%s" % (File, str(e)))\r
-        Data = None\r
-    finally:\r
-        if Fd != None:\r
-            Fd.close()\r
-    return Data\r
-\r
-## Check if gvien file exists or not\r
-#\r
-#   @param      File    File name or path to be checked\r
-#   @param      Dir     The directory the file is relative to\r
-#\r
-#   @retval     True    if file exists\r
-#   @retval     False   if file doesn't exists\r
-#\r
-def ValidFile(File, Ext=None, Dir='.'):\r
-    if Ext != None:\r
-        Dummy, FileExt = os.path.splitext(File)\r
-        if FileExt.lower() != Ext.lower():\r
-            return False\r
-    Wd = os.getcwd()\r
-    os.chdir(Dir)\r
-    if not os.path.exists(File):\r
-        os.chdir(Wd)\r
-        return False\r
-    os.chdir(Wd)\r
-    return True\r
-\r
-## Get GUID value from given packages\r
-#\r
-#   @param      CName           The CName of the GUID\r
-#   @param      PackageList     List of packages looking-up in\r
-#\r
-#   @retval     GuidValue   if the CName is found in any given package\r
-#   @retval     None        if the CName is not found in all given packages\r
-#\r
-def GuidValue(CName, PackageList):\r
-    for P in PackageList:\r
-        if CName in P.Guids:\r
-            return P.Guids[CName]\r
-        if CName in P.Protocols:\r
-            return P.Protocols[CName]\r
-        if CName in P.Ppis:\r
-            return P.Ppis[CName]\r
-    return None\r
-\r
-## A string template class\r
-#\r
-#  This class implements a template for string replacement. A string template\r
-#  looks like following\r
-#\r
-#       ${BEGIN} other_string ${placeholder_name} other_string ${END}\r
-#\r
-#  The string between ${BEGIN} and ${END} will be repeated as many times as the\r
-#  length of "placeholder_name", which is a list passed through a dict. The\r
-#  "placeholder_name" is the key name of the dict. The ${BEGIN} and ${END} can\r
-#  be not used and, in this case, the "placeholder_name" must not a list and it\r
-#  will just be replaced once.\r
-#\r
-class TemplateString(object):\r
-    ## Constructor\r
-    def __init__(self):\r
-        self.String = ''\r
-\r
-    ## str() operator\r
-    #\r
-    #   @retval     string  The string replaced\r
-    #\r
-    def __str__(self):\r
-        return self.String\r
-\r
-    ## Replace the string template with dictionary of placeholders\r
-    #\r
-    #   @param      AppendString    The string template to append\r
-    #   @param      Dictionary      The placeholder dictionaries\r
-    #\r
-    def Append(self, AppendString, Dictionary=None):\r
-        if Dictionary == None:\r
-            self.String += AppendString\r
-            return\r
-\r
-        # replace repeat ones, enclosed by ${BEGIN} and $(END)\r
-        while True:\r
-            Start = AppendString.find('${BEGIN}')\r
-            if Start < 0:\r
-                break\r
-            End   = AppendString.find('${END}')\r
-\r
-            # exclude the ${BEGIN} and ${END}\r
-            SubString = AppendString[Start + 8 : End]\r
-\r
-            RepeatTime = -1\r
-            SubDict = {}\r
-            PlaceholderList = gPlaceholderPattern.findall(SubString)\r
-            for Key in PlaceholderList:\r
-                if Key not in Dictionary:\r
-                    continue\r
-\r
-                Value = Dictionary[Key]\r
-                if type(Value) != type([]):\r
-                    continue\r
-\r
-                SubDict[Key] = ""\r
-                if RepeatTime < 0:\r
-                    RepeatTime = len(Value)\r
-                elif RepeatTime != len(Value):\r
-                    EdkLogger.error("TemplateString", PARAMETER_INVALID, Key + " has different repeat time from others!",\r
-                                    ExtraData=str(Dictionary))\r
-\r
-            NewString = ''\r
-            for Index in range(0, RepeatTime):\r
-                for Key in SubDict:\r
-                    SubDict[Key] = Dictionary[Key][Index]\r
-                NewString += string.Template(SubString).safe_substitute(SubDict)\r
-            AppendString = AppendString[0:Start] + NewString + AppendString[End + 6:]\r
-\r
-        # replace single ones\r
-        SubDict = {}\r
-        for Key in Dictionary:\r
-            Value = Dictionary[Key]\r
-            if type(Value) == type([]):\r
-                continue\r
-            SubDict[Key] = Value\r
-        AppendString = string.Template(AppendString).safe_substitute(SubDict)\r
-\r
-        self.String += AppendString\r
-\r
-## Progress indicator class\r
-#\r
-#  This class makes use of thread to print progress on console.\r
-#\r
-class Progressor:\r
-    # for avoiding deadloop\r
-    _StopFlag = None\r
-    _ProgressThread = None\r
-    ## Constructor\r
-    #\r
-    #   @param      OpenMessage     The string printed before progress charaters\r
-    #   @param      CloseMessage    The string printed after progress charaters\r
-    #   @param      ProgressChar    The charater used to indicate the progress\r
-    #   @param      Interval        The interval in seconds between two progress charaters\r
-    #\r
-    def __init__(self, OpenMessage="", CloseMessage="", ProgressChar='.', Interval=1):\r
-        self.PromptMessage = OpenMessage\r
-        self.CodaMessage = CloseMessage\r
-        self.ProgressChar = ProgressChar\r
-        self.Interval = Interval\r
-        if Progressor._StopFlag == None:\r
-            Progressor._StopFlag = threading.Event()\r
-\r
-    ## Start to print progress charater\r
-    #\r
-    #   @param      OpenMessage     The string printed before progress charaters\r
-    #\r
-    def Start(self, OpenMessage=None):\r
-        if OpenMessage != None:\r
-            self.PromptMessage = OpenMessage\r
-        Progressor._StopFlag.clear()\r
-        if Progressor._ProgressThread == None:\r
-            Progressor._ProgressThread = threading.Thread(target=self._ProgressThreadEntry)\r
-            Progressor._ProgressThread.setDaemon(False)\r
-            Progressor._ProgressThread.start()\r
-\r
-    ## Stop printing progress charater\r
-    #\r
-    #   @param      CloseMessage    The string printed after progress charaters\r
-    #\r
-    def Stop(self, CloseMessage=None):\r
-        OriginalCodaMessage = self.CodaMessage\r
-        if CloseMessage != None:\r
-            self.CodaMessage = CloseMessage\r
-        self.Abort()\r
-        self.CodaMessage = OriginalCodaMessage\r
-\r
-    ## Thread entry method\r
-    def _ProgressThreadEntry(self):\r
-        print self.PromptMessage,\r
-        sys.stdout.flush()\r
-        while not Progressor._StopFlag.isSet():\r
-            print self.ProgressChar,\r
-            sys.stdout.flush()\r
-            time.sleep(self.Interval)\r
-        print self.CodaMessage\r
-        sys.stdout.flush()\r
-\r
-    ## Abort the progress display\r
-    @staticmethod\r
-    def Abort():\r
-        if Progressor._StopFlag != None:\r
-            Progressor._StopFlag.set()\r
-        if Progressor._ProgressThread != None:\r
-            Progressor._ProgressThread.join()\r
-            Progressor._ProgressThread = None\r
-\r
-## A dict which can access its keys and/or values orderly\r
-#\r
-#  The class implements a new kind of dict which its keys or values can be\r
-#  accessed in the order they are added into the dict. It guarantees the order\r
-#  by making use of an internal list to keep a copy of keys.\r
-#\r
-class sdict(IterableUserDict):\r
-    ## Constructor\r
-    def __init__(self):\r
-        IterableUserDict.__init__(self)\r
-        self._key_list = []\r
-\r
-    ## [] operator\r
-    def __setitem__(self, key, value):\r
-        if key not in self._key_list:\r
-            self._key_list.append(key)\r
-        IterableUserDict.__setitem__(self, key, value)\r
-\r
-    ## del operator\r
-    def __delitem__(self, key):\r
-        self._key_list.remove(key)\r
-        IterableUserDict.__delitem__(self, key)\r
-\r
-    ## used in "for k in dict" loop to ensure the correct order\r
-    def __iter__(self):\r
-        return self.iterkeys()\r
-\r
-    ## len() support\r
-    def __len__(self):\r
-        return len(self._key_list)\r
-\r
-    ## "in" test support\r
-    def __contains__(self, key):\r
-        return key in self._key_list\r
-\r
-    ## indexof support\r
-    def index(self, key):\r
-        return self._key_list.index(key)\r
-\r
-    ## insert support\r
-    def insert(self, key, newkey, newvalue, order):\r
-        index = self._key_list.index(key)\r
-        if order == 'BEFORE':\r
-            self._key_list.insert(index, newkey)\r
-            IterableUserDict.__setitem__(self, newkey, newvalue)\r
-        elif order == 'AFTER':\r
-            self._key_list.insert(index + 1, newkey)\r
-            IterableUserDict.__setitem__(self, newkey, newvalue)\r
-\r
-    ## append support\r
-    def append(self, sdict):\r
-        for key in sdict:\r
-            if key not in self._key_list:\r
-                self._key_list.append(key)\r
-            IterableUserDict.__setitem__(self, key, sdict[key])\r
-\r
-    def has_key(self, key):\r
-        return key in self._key_list\r
-\r
-    ## Empty the dict\r
-    def clear(self):\r
-        self._key_list = []\r
-        IterableUserDict.clear(self)\r
-\r
-    ## Return a copy of keys\r
-    def keys(self):\r
-        keys = []\r
-        for key in self._key_list:\r
-            keys.append(key)\r
-        return keys\r
-\r
-    ## Return a copy of values\r
-    def values(self):\r
-        values = []\r
-        for key in self._key_list:\r
-            values.append(self[key])\r
-        return values\r
-\r
-    ## Return a copy of (key, value) list\r
-    def items(self):\r
-        items = []\r
-        for key in self._key_list:\r
-            items.append((key, self[key]))\r
-        return items\r
-\r
-    ## Iteration support\r
-    def iteritems(self):\r
-        return iter(self.items())\r
-\r
-    ## Keys interation support\r
-    def iterkeys(self):\r
-        return iter(self.keys())\r
-\r
-    ## Values interation support\r
-    def itervalues(self):\r
-        return iter(self.values())\r
-\r
-    ## Return value related to a key, and remove the (key, value) from the dict\r
-    def pop(self, key, *dv):\r
-        value = None\r
-        if key in self._key_list:\r
-            value = self[key]\r
-            self.__delitem__(key)\r
-        elif len(dv) != 0 :\r
-            value = kv[0]\r
-        return value\r
-\r
-    ## Return (key, value) pair, and remove the (key, value) from the dict\r
-    def popitem(self):\r
-        key = self._key_list[-1]\r
-        value = self[key]\r
-        self.__delitem__(key)\r
-        return key, value\r
-\r
-    def update(self, dict=None, **kwargs):\r
-        if dict != None:\r
-            for k, v in dict.items():\r
-                self[k] = v\r
-        if len(kwargs):\r
-            for k, v in kwargs.items():\r
-                self[k] = v\r
-\r
-## Dictionary with restricted keys\r
-#\r
-class rdict(dict):\r
-    ## Constructor\r
-    def __init__(self, KeyList):\r
-        for Key in KeyList:\r
-            dict.__setitem__(self, Key, "")\r
-\r
-    ## []= operator\r
-    def __setitem__(self, key, value):\r
-        if key not in self:\r
-            EdkLogger.error("RestrictedDict", ATTRIBUTE_SET_FAILURE, "Key [%s] is not allowed" % key,\r
-                            ExtraData=", ".join(dict.keys(self)))\r
-        dict.__setitem__(self, key, value)\r
-\r
-    ## =[] operator\r
-    def __getitem__(self, key):\r
-        if key not in self:\r
-            return ""\r
-        return dict.__getitem__(self, key)\r
-\r
-    ## del operator\r
-    def __delitem__(self, key):\r
-        EdkLogger.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED, ExtraData="del")\r
-\r
-    ## Empty the dict\r
-    def clear(self):\r
-        for Key in self:\r
-            self.__setitem__(Key, "")\r
-\r
-    ## Return value related to a key, and remove the (key, value) from the dict\r
-    def pop(self, key, *dv):\r
-        EdkLogger.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED, ExtraData="pop")\r
-\r
-    ## Return (key, value) pair, and remove the (key, value) from the dict\r
-    def popitem(self):\r
-        EdkLogger.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED, ExtraData="popitem")\r
-\r
-## Dictionary using prioritized list as key\r
-#\r
-class tdict:\r
-    _ListType = type([])\r
-    _TupleType = type(())\r
-    _Wildcard = 'COMMON'\r
-    _ValidWildcardList = ['COMMON', 'DEFAULT', 'ALL', '', '*', 'PLATFORM']\r
-\r
-    def __init__(self, _Single_=False, _Level_=2):\r
-        self._Level_ = _Level_\r
-        self.data = {}\r
-        self._Single_ = _Single_\r
-\r
-    # =[] operator\r
-    def __getitem__(self, key):\r
-        KeyType = type(key)\r
-        RestKeys = None\r
-        if KeyType == self._ListType or KeyType == self._TupleType:\r
-            FirstKey = key[0]\r
-            if len(key) > 1:\r
-                RestKeys = key[1:]\r
-            elif self._Level_ > 1:\r
-                RestKeys = [self._Wildcard for i in range(0, self._Level_-1)]\r
-        else:\r
-            FirstKey = key\r
-            if self._Level_ > 1:\r
-                RestKeys = [self._Wildcard for i in range(0, self._Level_-1)]\r
-\r
-        if FirstKey == None or str(FirstKey).upper() in self._ValidWildcardList:\r
-            FirstKey = self._Wildcard\r
-\r
-        if self._Single_:\r
-            return self._GetSingleValue(FirstKey, RestKeys)\r
-        else:\r
-            return self._GetAllValues(FirstKey, RestKeys)\r
-\r
-    def _GetSingleValue(self, FirstKey, RestKeys):\r
-        Value = None\r
-        #print "%s-%s" % (FirstKey, self._Level_) ,\r
-        if self._Level_ > 1:\r
-            if FirstKey == self._Wildcard:\r
-                if FirstKey in self.data:\r
-                    Value = self.data[FirstKey][RestKeys]\r
-                if Value == None:\r
-                    for Key in self.data:\r
-                        Value = self.data[Key][RestKeys]\r
-                        if Value != None: break\r
-            else:\r
-                if FirstKey in self.data:\r
-                    Value = self.data[FirstKey][RestKeys]\r
-                if Value == None and self._Wildcard in self.data:\r
-                    #print "Value=None"\r
-                    Value = self.data[self._Wildcard][RestKeys]\r
-        else:\r
-            if FirstKey == self._Wildcard:\r
-                if FirstKey in self.data:\r
-                    Value = self.data[FirstKey]\r
-                if Value == None:\r
-                    for Key in self.data:\r
-                        Value = self.data[Key]\r
-                        if Value != None: break\r
-            else:\r
-                if FirstKey in self.data:\r
-                    Value = self.data[FirstKey]\r
-                elif self._Wildcard in self.data:\r
-                    Value = self.data[self._Wildcard]\r
-        return Value\r
-\r
-    def _GetAllValues(self, FirstKey, RestKeys):\r
-        Value = []\r
-        if self._Level_ > 1:\r
-            if FirstKey == self._Wildcard:\r
-                for Key in self.data:\r
-                    Value += self.data[Key][RestKeys]\r
-            else:\r
-                if FirstKey in self.data:\r
-                    Value += self.data[FirstKey][RestKeys]\r
-                if self._Wildcard in self.data:\r
-                    Value += self.data[self._Wildcard][RestKeys]\r
-        else:\r
-            if FirstKey == self._Wildcard:\r
-                for Key in self.data:\r
-                    Value.append(self.data[Key])\r
-            else:\r
-                if FirstKey in self.data:\r
-                    Value.append(self.data[FirstKey])\r
-                if self._Wildcard in self.data:\r
-                    Value.append(self.data[self._Wildcard])\r
-        return Value\r
-\r
-    ## []= operator\r
-    def __setitem__(self, key, value):\r
-        KeyType = type(key)\r
-        RestKeys = None\r
-        if KeyType == self._ListType or KeyType == self._TupleType:\r
-            FirstKey = key[0]\r
-            if len(key) > 1:\r
-                RestKeys = key[1:]\r
-            else:\r
-                RestKeys = [self._Wildcard for i in range(0, self._Level_-1)]\r
-        else:\r
-            FirstKey = key\r
-            if self._Level_ > 1:\r
-                RestKeys = [self._Wildcard for i in range(0, self._Level_-1)]\r
-\r
-        if FirstKey in self._ValidWildcardList:\r
-            FirstKey = self._Wildcard\r
-\r
-        if FirstKey not in self.data and self._Level_ > 0:\r
-            self.data[FirstKey] = tdict(self._Single_, self._Level_ - 1)\r
-\r
-        if self._Level_ > 1:\r
-            self.data[FirstKey][RestKeys] = value\r
-        else:\r
-            self.data[FirstKey] = value\r
-\r
-    def SetGreedyMode(self):\r
-        self._Single_ = False\r
-        if self._Level_ > 1:\r
-            for Key in self.data:\r
-                self.data[Key].SetGreedyMode()\r
-\r
-    def SetSingleMode(self):\r
-        self._Single_ = True\r
-        if self._Level_ > 1:\r
-            for Key in self.data:\r
-                self.data[Key].SetSingleMode()\r
-\r
-## Boolean chain list\r
-#\r
-class Blist(UserList):\r
-    def __init__(self, initlist=None):\r
-        UserList.__init__(self, initlist)\r
-    def __setitem__(self, i, item):\r
-        if item not in [True, False]:\r
-            if item == 0:\r
-                item = False\r
-            else:\r
-                item = True\r
-        self.data[i] = item\r
-    def _GetResult(self):\r
-        Value = True\r
-        for item in self.data:\r
-            Value &= item\r
-        return Value\r
-    Result = property(_GetResult)\r
-\r
-def ParseConsoleLog(Filename):\r
-    Opr = open(os.path.normpath(Filename), 'r')\r
-    Opw = open(os.path.normpath(Filename + '.New'), 'w+')\r
-    for Line in Opr.readlines():\r
-        if Line.find('.efi') > -1:\r
-            Line = Line[Line.rfind(' ') : Line.rfind('.efi')].strip()\r
-            Opw.write('%s\n' % Line)\r
-\r
-    Opr.close()\r
-    Opw.close()\r
-\r
-##\r
-#\r
-# This acts like the main() function for the script, unless it is 'import'ed into another\r
-# script.\r
-#\r
-if __name__ == '__main__':\r
-    ParseConsoleLog('C:\\R861\\Log\\Tiger.log')\r
-#    print GuidStringToGuidStructureString('6441F818-6362-4E44-B570-7DBA31DD2453')\r
-#    d = tdict(True, 3)\r
-#    d['COMMON', 'PEIM', "A",] = 1\r
-#    d['COMMON', 'DXE_CORE', 'B'] = 2\r
-#    d['IA32', 'DXE_CORE', 'C'] = 3\r
-#\r
-#    print d['IA32', 'DXE_CORE', 'C']\r
-\r
-#    s = sdict()\r
-#    s[1] = 1\r
-#    s[3] = 3\r
-#    s[4] = 4\r
-#    s[6] = 6\r
-#    print s.index(3)\r
-#    s.insert(3, 2, 2, 'BEFORE')\r
-#    print s.index(3)\r
-#    print s.index(4)\r
-#    s.insert(4, 5, 5, 'AFTER')\r
-#    print s.keys()\r
-#    print s.values()\r
-#    for item in s:\r
-#        print item, s[item]\r
-\r
+## @file
+# Common routines used by all tools
+#
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+##
+# Import Modules
+#
+import os
+import sys
+import string
+import thread
+import threading
+import time
+import re
+import cPickle
+from UserDict import IterableUserDict
+from UserList import UserList
+
+from Common import EdkLogger as EdkLogger
+from BuildToolError import *
+
+## Regular expression used to find out place holders in string template
+gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE|re.UNICODE)
+
+## Dictionary used to store file time stamp for quick re-access
+gFileTimeStampCache = {}    # {file path : file time stamp}
+
+## Dictionary used to store dependencies of files
+gDependencyDatabase = {}    # arch : {file path : [dependent files list]}
+
+## callback routine for processing variable option
+#
+# This function can be used to process variable number of option values. The
+# typical usage of it is specify architecure list on command line.
+# (e.g. <tool> -a IA32 X64 IPF)
+#
+# @param  Option        Standard callback function parameter
+# @param  OptionString  Standard callback function parameter
+# @param  Value         Standard callback function parameter
+# @param  Parser        Standard callback function parameter
+#
+# @retval
+#
+def ProcessVariableArgument(Option, OptionString, Value, Parser):
+    assert Value is None
+    Value = []
+    RawArgs = Parser.rargs
+    while RawArgs:
+        Arg = RawArgs[0]
+        if (Arg[:2] == "--" and len(Arg) > 2) or \
+           (Arg[:1] == "-" and len(Arg) > 1 and Arg[1] != "-"):
+            break
+        Value.append(Arg)
+        del RawArgs[0]
+    setattr(Parser.values, Option.dest, Value)
+
+## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C structure style
+#
+#   @param      Guid    The GUID string
+#
+#   @retval     string  The GUID string in C structure style
+#
+def GuidStringToGuidStructureString(Guid):
+    GuidList = Guid.split('-')
+    Result = '{'
+    for Index in range(0,3,1):
+        Result = Result + '0x' + GuidList[Index] + ', '
+    Result = Result + '{0x' + GuidList[3][0:2] + ', 0x' + GuidList[3][2:4]
+    for Index in range(0,12,2):
+        Result = Result + ', 0x' + GuidList[4][Index:Index+2]
+    Result += '}}'
+    return Result
+
+## Convert GUID string in C structure style to xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+#
+#   @param      GuidValue   The GUID value in C structure format
+#
+#   @retval     string      The GUID value in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format
+#
+def GuidStructureStringToGuidString(GuidValue):
+    guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "").replace(";", "")
+    guidValueList = guidValueString.split(",")
+    if len(guidValueList) != 11:
+        return ''
+        #EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue)
+    try:
+        return "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" % (
+                int(guidValueList[0], 16),
+                int(guidValueList[1], 16),
+                int(guidValueList[2], 16),
+                int(guidValueList[3], 16),
+                int(guidValueList[4], 16),
+                int(guidValueList[5], 16),
+                int(guidValueList[6], 16),
+                int(guidValueList[7], 16),
+                int(guidValueList[8], 16),
+                int(guidValueList[9], 16),
+                int(guidValueList[10], 16)
+                )
+    except:
+        return ''
+
+## Convert GUID string in C structure style to xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx
+#
+#   @param      GuidValue   The GUID value in C structure format
+#
+#   @retval     string      The GUID value in xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx format
+#
+def GuidStructureStringToGuidValueName(GuidValue):
+    guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "")
+    guidValueList = guidValueString.split(",")
+    if len(guidValueList) != 11:
+        EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue)
+    return "%08x_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x" % (
+            int(guidValueList[0], 16),
+            int(guidValueList[1], 16),
+            int(guidValueList[2], 16),
+            int(guidValueList[3], 16),
+            int(guidValueList[4], 16),
+            int(guidValueList[5], 16),
+            int(guidValueList[6], 16),
+            int(guidValueList[7], 16),
+            int(guidValueList[8], 16),
+            int(guidValueList[9], 16),
+            int(guidValueList[10], 16)
+            )
+
+## Create directories
+#
+#   @param      Directory   The directory name
+#
+def CreateDirectory(Directory):
+    if Directory == None or Directory.strip() == "":
+        return True
+    try:
+        if not os.access(Directory, os.F_OK):
+            os.makedirs(Directory)
+    except:
+        return False
+    return True
+
+## Check if given file is changed or not
+#
+#  This method is used to check if a file is changed or not between two build
+#  actions. It makes use a cache to store files timestamp.
+#
+#   @param      File    The path of file
+#
+#   @retval     True    If the given file is changed, doesn't exist, or can't be
+#                       found in timestamp cache
+#   @retval     False   If the given file is changed
+#
+def IsChanged(File):
+    if not os.path.exists(File):
+        return True
+
+    FileState = os.stat(File)
+    TimeStamp = FileState[-2]
+
+    if File in gFileTimeStampCache and TimeStamp == gFileTimeStampCache[File]:
+        FileChanged = False
+    else:
+        FileChanged = True
+        gFileTimeStampCache[File] = TimeStamp
+
+    return FileChanged
+
+## Store content in file
+#
+#  This method is used to save file only when its content is changed. This is
+#  quite useful for "make" system to decide what will be re-built and what won't.
+#
+#   @param      File            The path of file
+#   @param      Content         The new content of the file
+#   @param      IsBinaryFile    The flag indicating if the file is binary file or not
+#
+#   @retval     True            If the file content is changed and the file is renewed
+#   @retval     False           If the file content is the same
+#
+def SaveFileOnChange(File, Content, IsBinaryFile=True):
+    if IsBinaryFile:
+        BinaryFlag = 'b'
+    else:
+        BinaryFlag = ''
+    Fd = None
+    if os.path.exists(File):
+        try:
+            Fd = open(File, "r"+BinaryFlag)
+        except:
+            EdkLogger.error(None, FILE_OPEN_FAILURE, ExtraData=File)
+        FileSize = os.fstat(Fd.fileno()).st_size
+        if len(Content) == FileSize and Content == Fd.read():
+            Fd.close()
+            return False
+        Fd.close()
+        # os.remove(File) # seems creating new file is faster than overwriting old one
+    CreateDirectory(os.path.dirname(File))
+    try:
+        Fd = open(File, "w"+BinaryFlag)
+    except:
+        EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData=File)
+    Fd.write(Content)
+    Fd.close()
+    return True
+
+## Make a Python object persistent on file system
+#
+#   @param      Data    The object to be stored in file
+#   @param      File    The path of file to store the object
+#
+def DataDump(Data, File):
+    Fd = None
+    try:
+        Fd = open(File, 'wb')
+        cPickle.dump(Data, Fd, cPickle.HIGHEST_PROTOCOL)
+    except:
+        EdkLogger.error("", FILE_OPEN_FAILURE, ExtraData=File, RaiseError=False)
+    finally:
+        if Fd != None:
+            Fd.close()
+
+## Restore a Python object from a file
+#
+#   @param      File    The path of file stored the object
+#
+#   @retval     object  A python object
+#   @retval     None    If failure in file operation
+#
+def DataRestore(File):
+    Data = None
+    Fd = None
+    try:
+        Fd = open(File, 'rb')
+        Data = cPickle.load(Fd)
+    except Exception, e:
+        EdkLogger.verbose("Failed to load [%s]\n\t%s" % (File, str(e)))
+        Data = None
+    finally:
+        if Fd != None:
+            Fd.close()
+    return Data
+
+## Check if gvien file exists or not
+#
+#   @param      File    File name or path to be checked
+#   @param      Dir     The directory the file is relative to
+#
+#   @retval     True    if file exists
+#   @retval     False   if file doesn't exists
+#
+def ValidFile(File, Ext=None, Dir='.'):
+    if Ext != None:
+        Dummy, FileExt = os.path.splitext(File)
+        if FileExt.lower() != Ext.lower():
+            return False
+    Wd = os.getcwd()
+    os.chdir(Dir)
+    if not os.path.exists(File):
+        os.chdir(Wd)
+        return False
+    os.chdir(Wd)
+    return True
+
+## Get GUID value from given packages
+#
+#   @param      CName           The CName of the GUID
+#   @param      PackageList     List of packages looking-up in
+#
+#   @retval     GuidValue   if the CName is found in any given package
+#   @retval     None        if the CName is not found in all given packages
+#
+def GuidValue(CName, PackageList):
+    for P in PackageList:
+        if CName in P.Guids:
+            return P.Guids[CName]
+        if CName in P.Protocols:
+            return P.Protocols[CName]
+        if CName in P.Ppis:
+            return P.Ppis[CName]
+    return None
+
+## A string template class
+#
+#  This class implements a template for string replacement. A string template
+#  looks like following
+#
+#       ${BEGIN} other_string ${placeholder_name} other_string ${END}
+#
+#  The string between ${BEGIN} and ${END} will be repeated as many times as the
+#  length of "placeholder_name", which is a list passed through a dict. The
+#  "placeholder_name" is the key name of the dict. The ${BEGIN} and ${END} can
+#  be not used and, in this case, the "placeholder_name" must not a list and it
+#  will just be replaced once.
+#
+class TemplateString(object):
+    ## Constructor
+    def __init__(self):
+        self.String = ''
+
+    ## str() operator
+    #
+    #   @retval     string  The string replaced
+    #
+    def __str__(self):
+        return self.String
+
+    ## Replace the string template with dictionary of placeholders
+    #
+    #   @param      AppendString    The string template to append
+    #   @param      Dictionary      The placeholder dictionaries
+    #
+    def Append(self, AppendString, Dictionary=None):
+        if Dictionary == None:
+            self.String += AppendString
+            return
+
+        # replace repeat ones, enclosed by ${BEGIN} and $(END)
+        while True:
+            Start = AppendString.find('${BEGIN}')
+            if Start < 0:
+                break
+            End   = AppendString.find('${END}')
+
+            # exclude the ${BEGIN} and ${END}
+            SubString = AppendString[Start + 8 : End]
+
+            RepeatTime = -1
+            SubDict = {}
+            PlaceholderList = gPlaceholderPattern.findall(SubString)
+            for Key in PlaceholderList:
+                if Key not in Dictionary:
+                    continue
+
+                Value = Dictionary[Key]
+                if type(Value) != type([]):
+                    continue
+
+                SubDict[Key] = ""
+                if RepeatTime < 0:
+                    RepeatTime = len(Value)
+                elif RepeatTime != len(Value):
+                    EdkLogger.error("TemplateString", PARAMETER_INVALID, Key + " has different repeat time from others!",
+                                    ExtraData=str(Dictionary))
+
+            NewString = ''
+            for Index in range(0, RepeatTime):
+                for Key in SubDict:
+                    SubDict[Key] = Dictionary[Key][Index]
+                NewString += string.Template(SubString).safe_substitute(SubDict)
+            AppendString = AppendString[0:Start] + NewString + AppendString[End + 6:]
+
+        # replace single ones
+        SubDict = {}
+        for Key in Dictionary:
+            Value = Dictionary[Key]
+            if type(Value) == type([]):
+                continue
+            SubDict[Key] = Value
+        AppendString = string.Template(AppendString).safe_substitute(SubDict)
+
+        self.String += AppendString
+
+## Progress indicator class
+#
+#  This class makes use of thread to print progress on console.
+#
+class Progressor:
+    # for avoiding deadloop
+    _StopFlag = None
+    _ProgressThread = None
+    ## Constructor
+    #
+    #   @param      OpenMessage     The string printed before progress charaters
+    #   @param      CloseMessage    The string printed after progress charaters
+    #   @param      ProgressChar    The charater used to indicate the progress
+    #   @param      Interval        The interval in seconds between two progress charaters
+    #
+    def __init__(self, OpenMessage="", CloseMessage="", ProgressChar='.', Interval=1):
+        self.PromptMessage = OpenMessage
+        self.CodaMessage = CloseMessage
+        self.ProgressChar = ProgressChar
+        self.Interval = Interval
+        if Progressor._StopFlag == None:
+            Progressor._StopFlag = threading.Event()
+
+    ## Start to print progress charater
+    #
+    #   @param      OpenMessage     The string printed before progress charaters
+    #
+    def Start(self, OpenMessage=None):
+        if OpenMessage != None:
+            self.PromptMessage = OpenMessage
+        Progressor._StopFlag.clear()
+        if Progressor._ProgressThread == None:
+            Progressor._ProgressThread = threading.Thread(target=self._ProgressThreadEntry)
+            Progressor._ProgressThread.setDaemon(False)
+            Progressor._ProgressThread.start()
+
+    ## Stop printing progress charater
+    #
+    #   @param      CloseMessage    The string printed after progress charaters
+    #
+    def Stop(self, CloseMessage=None):
+        OriginalCodaMessage = self.CodaMessage
+        if CloseMessage != None:
+            self.CodaMessage = CloseMessage
+        self.Abort()
+        self.CodaMessage = OriginalCodaMessage
+
+    ## Thread entry method
+    def _ProgressThreadEntry(self):
+        print self.PromptMessage,
+        sys.stdout.flush()
+        while not Progressor._StopFlag.isSet():
+            print self.ProgressChar,
+            sys.stdout.flush()
+            time.sleep(self.Interval)
+        print self.CodaMessage
+        sys.stdout.flush()
+
+    ## Abort the progress display
+    @staticmethod
+    def Abort():
+        if Progressor._StopFlag != None:
+            Progressor._StopFlag.set()
+        if Progressor._ProgressThread != None:
+            Progressor._ProgressThread.join()
+            Progressor._ProgressThread = None
+
+## A dict which can access its keys and/or values orderly
+#
+#  The class implements a new kind of dict which its keys or values can be
+#  accessed in the order they are added into the dict. It guarantees the order
+#  by making use of an internal list to keep a copy of keys.
+#
+class sdict(IterableUserDict):
+    ## Constructor
+    def __init__(self):
+        IterableUserDict.__init__(self)
+        self._key_list = []
+
+    ## [] operator
+    def __setitem__(self, key, value):
+        if key not in self._key_list:
+            self._key_list.append(key)
+        IterableUserDict.__setitem__(self, key, value)
+
+    ## del operator
+    def __delitem__(self, key):
+        self._key_list.remove(key)
+        IterableUserDict.__delitem__(self, key)
+
+    ## used in "for k in dict" loop to ensure the correct order
+    def __iter__(self):
+        return self.iterkeys()
+
+    ## len() support
+    def __len__(self):
+        return len(self._key_list)
+
+    ## "in" test support
+    def __contains__(self, key):
+        return key in self._key_list
+
+    ## indexof support
+    def index(self, key):
+        return self._key_list.index(key)
+
+    ## insert support
+    def insert(self, key, newkey, newvalue, order):
+        index = self._key_list.index(key)
+        if order == 'BEFORE':
+            self._key_list.insert(index, newkey)
+            IterableUserDict.__setitem__(self, newkey, newvalue)
+        elif order == 'AFTER':
+            self._key_list.insert(index + 1, newkey)
+            IterableUserDict.__setitem__(self, newkey, newvalue)
+
+    ## append support
+    def append(self, sdict):
+        for key in sdict:
+            if key not in self._key_list:
+                self._key_list.append(key)
+            IterableUserDict.__setitem__(self, key, sdict[key])
+
+    def has_key(self, key):
+        return key in self._key_list
+
+    ## Empty the dict
+    def clear(self):
+        self._key_list = []
+        IterableUserDict.clear(self)
+
+    ## Return a copy of keys
+    def keys(self):
+        keys = []
+        for key in self._key_list:
+            keys.append(key)
+        return keys
+
+    ## Return a copy of values
+    def values(self):
+        values = []
+        for key in self._key_list:
+            values.append(self[key])
+        return values
+
+    ## Return a copy of (key, value) list
+    def items(self):
+        items = []
+        for key in self._key_list:
+            items.append((key, self[key]))
+        return items
+
+    ## Iteration support
+    def iteritems(self):
+        return iter(self.items())
+
+    ## Keys interation support
+    def iterkeys(self):
+        return iter(self.keys())
+
+    ## Values interation support
+    def itervalues(self):
+        return iter(self.values())
+
+    ## Return value related to a key, and remove the (key, value) from the dict
+    def pop(self, key, *dv):
+        value = None
+        if key in self._key_list:
+            value = self[key]
+            self.__delitem__(key)
+        elif len(dv) != 0 :
+            value = kv[0]
+        return value
+
+    ## Return (key, value) pair, and remove the (key, value) from the dict
+    def popitem(self):
+        key = self._key_list[-1]
+        value = self[key]
+        self.__delitem__(key)
+        return key, value
+
+    def update(self, dict=None, **kwargs):
+        if dict != None:
+            for k, v in dict.items():
+                self[k] = v
+        if len(kwargs):
+            for k, v in kwargs.items():
+                self[k] = v
+
+## Dictionary with restricted keys
+#
+class rdict(dict):
+    ## Constructor
+    def __init__(self, KeyList):
+        for Key in KeyList:
+            dict.__setitem__(self, Key, "")
+
+    ## []= operator
+    def __setitem__(self, key, value):
+        if key not in self:
+            EdkLogger.error("RestrictedDict", ATTRIBUTE_SET_FAILURE, "Key [%s] is not allowed" % key,
+                            ExtraData=", ".join(dict.keys(self)))
+        dict.__setitem__(self, key, value)
+
+    ## =[] operator
+    def __getitem__(self, key):
+        if key not in self:
+            return ""
+        return dict.__getitem__(self, key)
+
+    ## del operator
+    def __delitem__(self, key):
+        EdkLogger.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED, ExtraData="del")
+
+    ## Empty the dict
+    def clear(self):
+        for Key in self:
+            self.__setitem__(Key, "")
+
+    ## Return value related to a key, and remove the (key, value) from the dict
+    def pop(self, key, *dv):
+        EdkLogger.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED, ExtraData="pop")
+
+    ## Return (key, value) pair, and remove the (key, value) from the dict
+    def popitem(self):
+        EdkLogger.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED, ExtraData="popitem")
+
+## Dictionary using prioritized list as key
+#
+class tdict:
+    _ListType = type([])
+    _TupleType = type(())
+    _Wildcard = 'COMMON'
+    _ValidWildcardList = ['COMMON', 'DEFAULT', 'ALL', '', '*', 'PLATFORM']
+
+    def __init__(self, _Single_=False, _Level_=2):
+        self._Level_ = _Level_
+        self.data = {}
+        self._Single_ = _Single_
+
+    # =[] operator
+    def __getitem__(self, key):
+        KeyType = type(key)
+        RestKeys = None
+        if KeyType == self._ListType or KeyType == self._TupleType:
+            FirstKey = key[0]
+            if len(key) > 1:
+                RestKeys = key[1:]
+            elif self._Level_ > 1:
+                RestKeys = [self._Wildcard for i in range(0, self._Level_-1)]
+        else:
+            FirstKey = key
+            if self._Level_ > 1:
+                RestKeys = [self._Wildcard for i in range(0, self._Level_-1)]
+
+        if FirstKey == None or str(FirstKey).upper() in self._ValidWildcardList:
+            FirstKey = self._Wildcard
+
+        if self._Single_:
+            return self._GetSingleValue(FirstKey, RestKeys)
+        else:
+            return self._GetAllValues(FirstKey, RestKeys)
+
+    def _GetSingleValue(self, FirstKey, RestKeys):
+        Value = None
+        #print "%s-%s" % (FirstKey, self._Level_) ,
+        if self._Level_ > 1:
+            if FirstKey == self._Wildcard:
+                if FirstKey in self.data:
+                    Value = self.data[FirstKey][RestKeys]
+                if Value == None:
+                    for Key in self.data:
+                        Value = self.data[Key][RestKeys]
+                        if Value != None: break
+            else:
+                if FirstKey in self.data:
+                    Value = self.data[FirstKey][RestKeys]
+                if Value == None and self._Wildcard in self.data:
+                    #print "Value=None"
+                    Value = self.data[self._Wildcard][RestKeys]
+        else:
+            if FirstKey == self._Wildcard:
+                if FirstKey in self.data:
+                    Value = self.data[FirstKey]
+                if Value == None:
+                    for Key in self.data:
+                        Value = self.data[Key]
+                        if Value != None: break
+            else:
+                if FirstKey in self.data:
+                    Value = self.data[FirstKey]
+                elif self._Wildcard in self.data:
+                    Value = self.data[self._Wildcard]
+        return Value
+
+    def _GetAllValues(self, FirstKey, RestKeys):
+        Value = []
+        if self._Level_ > 1:
+            if FirstKey == self._Wildcard:
+                for Key in self.data:
+                    Value += self.data[Key][RestKeys]
+            else:
+                if FirstKey in self.data:
+                    Value += self.data[FirstKey][RestKeys]
+                if self._Wildcard in self.data:
+                    Value += self.data[self._Wildcard][RestKeys]
+        else:
+            if FirstKey == self._Wildcard:
+                for Key in self.data:
+                    Value.append(self.data[Key])
+            else:
+                if FirstKey in self.data:
+                    Value.append(self.data[FirstKey])
+                if self._Wildcard in self.data:
+                    Value.append(self.data[self._Wildcard])
+        return Value
+
+    ## []= operator
+    def __setitem__(self, key, value):
+        KeyType = type(key)
+        RestKeys = None
+        if KeyType == self._ListType or KeyType == self._TupleType:
+            FirstKey = key[0]
+            if len(key) > 1:
+                RestKeys = key[1:]
+            else:
+                RestKeys = [self._Wildcard for i in range(0, self._Level_-1)]
+        else:
+            FirstKey = key
+            if self._Level_ > 1:
+                RestKeys = [self._Wildcard for i in range(0, self._Level_-1)]
+
+        if FirstKey in self._ValidWildcardList:
+            FirstKey = self._Wildcard
+
+        if FirstKey not in self.data and self._Level_ > 0:
+            self.data[FirstKey] = tdict(self._Single_, self._Level_ - 1)
+
+        if self._Level_ > 1:
+            self.data[FirstKey][RestKeys] = value
+        else:
+            self.data[FirstKey] = value
+
+    def SetGreedyMode(self):
+        self._Single_ = False
+        if self._Level_ > 1:
+            for Key in self.data:
+                self.data[Key].SetGreedyMode()
+
+    def SetSingleMode(self):
+        self._Single_ = True
+        if self._Level_ > 1:
+            for Key in self.data:
+                self.data[Key].SetSingleMode()
+
+## Boolean chain list
+#
+class Blist(UserList):
+    def __init__(self, initlist=None):
+        UserList.__init__(self, initlist)
+    def __setitem__(self, i, item):
+        if item not in [True, False]:
+            if item == 0:
+                item = False
+            else:
+                item = True
+        self.data[i] = item
+    def _GetResult(self):
+        Value = True
+        for item in self.data:
+            Value &= item
+        return Value
+    Result = property(_GetResult)
+
+def ParseConsoleLog(Filename):
+    Opr = open(os.path.normpath(Filename), 'r')
+    Opw = open(os.path.normpath(Filename + '.New'), 'w+')
+    for Line in Opr.readlines():
+        if Line.find('.efi') > -1:
+            Line = Line[Line.rfind(' ') : Line.rfind('.efi')].strip()
+            Opw.write('%s\n' % Line)
+
+    Opr.close()
+    Opw.close()
+
+##
+#
+# This acts like the main() function for the script, unless it is 'import'ed into another
+# script.
+#
+if __name__ == '__main__':
+    ParseConsoleLog('C:\\R861\\Log\\Tiger.log')
+#    print GuidStringToGuidStructureString('6441F818-6362-4E44-B570-7DBA31DD2453')
+#    d = tdict(True, 3)
+#    d['COMMON', 'PEIM', "A",] = 1
+#    d['COMMON', 'DXE_CORE', 'B'] = 2
+#    d['IA32', 'DXE_CORE', 'C'] = 3
+#
+#    print d['IA32', 'DXE_CORE', 'C']
+
+#    s = sdict()
+#    s[1] = 1
+#    s[3] = 3
+#    s[4] = 4
+#    s[6] = 6
+#    print s.index(3)
+#    s.insert(3, 2, 2, 'BEFORE')
+#    print s.index(3)
+#    print s.index(4)
+#    s.insert(4, 5, 5, 'AFTER')
+#    print s.keys()
+#    print s.values()
+#    for item in s:
+#        print item, s[item]
+