## @file
# Create makefile for MS nmake and GNU make
#
# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#

## Import Modules
#
from __future__ import absolute_import
import Common.LongFilePathOs as os
import sys
import string
import re
import os.path as path
from Common import EdkLogger
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
from Common.BuildToolError import *
from Common.Misc import *
from Common.StringUtils import *
from .BuildEngine import *
import Common.GlobalData as GlobalData
from collections import OrderedDict
from Common.DataType import TAB_COMPILER_MSFT

## Regular expression for finding header file inclusions
gIncludePattern = re.compile(r"^[ \t]*[#%]?[ \t]*include(?:[ \t]*(?:\\(?:\r\n|\r|\n))*[ \t]*)*(?:\(?[\"<]?[ \t]*)([-\w.\\/() \t]+)(?:[ \t]*[\">]?\)?)", re.MULTILINE | re.UNICODE | re.IGNORECASE)

## Regular expression for matching macro used in header file inclusion
gMacroPattern = re.compile("([_A-Z][_A-Z0-9]*)[ \t]*\\((.+)\\)", re.UNICODE)

gIsFileMap = {}

## pattern for include style in Edk.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,
}

NMAKE_FILETYPE = "nmake"
GMAKE_FILETYPE = "gmake"
WIN32_PLATFORM = "win32"
POSIX_PLATFORM = "posix"

## 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_ = TemplateString('')

    _DEFAULT_FILE_NAME_ = "Makefile"

    ## default file name for each type of build file
    _FILE_NAME_ = {
        NMAKE_FILETYPE :   "Makefile",
        GMAKE_FILETYPE :   "GNUmakefile"
    }

    # Get Makefile name.
    def getMakefileName(self):
        if not self._FileType:
            return self._DEFAULT_FILE_NAME_
        else:
            return self._FILE_NAME_[self._FileType]

    ## 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_FILETYPE :   _MAKEFILE_HEADER % _FILE_NAME_[NMAKE_FILETYPE],
        GMAKE_FILETYPE :   _MAKEFILE_HEADER % _FILE_NAME_[GMAKE_FILETYPE]
    }

    ## 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_ = {
        WIN32_PLATFORM : {
            "CP"    :   "copy /y",
            "MV"    :   "move /y",
            "RM"    :   "del /f /q",
            "MD"    :   "mkdir",
            "RD"    :   "rmdir /s /q",
        },

        POSIX_PLATFORM : {
            "CP"    :   "cp -p -f",
            "MV"    :   "mv -f",
            "RM"    :   "rm -f",
            "MD"    :   "mkdir -p",
            "RD"    :   "rm -r -f",
        }
    }

    ## directory separator
    _SEP_ = {
        WIN32_PLATFORM :   "\\",
        POSIX_PLATFORM :   "/"
    }

    ## directory creation template
    _MD_TEMPLATE_ = {
        WIN32_PLATFORM :   'if not exist %(dir)s $(MD) %(dir)s',
        POSIX_PLATFORM :   "$(MD) %(dir)s"
    }

    ## directory removal template
    _RD_TEMPLATE_ = {
        WIN32_PLATFORM :   'if exist %(dir)s $(RD) %(dir)s',
        POSIX_PLATFORM :   "$(RD) %(dir)s"
    }
    ## cp if exist
    _CP_TEMPLATE_ = {
        WIN32_PLATFORM :   'if exist %(Src)s $(CP) %(Src)s %(Dst)s',
        POSIX_PLATFORM :   "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"
    }

    _CD_TEMPLATE_ = {
        WIN32_PLATFORM :   'if exist %(dir)s cd %(dir)s',
        POSIX_PLATFORM :   "test -e %(dir)s && cd %(dir)s"
    }

    _MAKE_TEMPLATE_ = {
        WIN32_PLATFORM :   'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s',
        POSIX_PLATFORM :   'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s'
    }

    _INCLUDE_CMD_ = {
        NMAKE_FILETYPE :   '!INCLUDE',
        GMAKE_FILETYPE :   "include"
    }

    _INC_FLAG_ = {TAB_COMPILER_MSFT : "/I", "GCC" : "-I", "INTEL" : "-I", "NASM" : "-I"}

    ## Constructor of BuildFile
    #
    #   @param  AutoGenObject   Object of AutoGen class
    #
    def __init__(self, AutoGenObject):
        self._AutoGenObject = AutoGenObject

        MakePath = AutoGenObject.BuildOption.get('MAKE', {}).get('PATH')
        if not MakePath:
            MakePath = AutoGenObject.ToolDefinition.get('MAKE', {}).get('PATH')
        if "nmake" in MakePath:
            self._FileType = NMAKE_FILETYPE
        else:
            self._FileType = GMAKE_FILETYPE

        if sys.platform == "win32":
            self._Platform = WIN32_PLATFORM
        else:
            self._Platform = POSIX_PLATFORM

    ## Create build file.
    #
    #  Only nmake and gmake are supported.
    #
    #  @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):
        FileContent = self._TEMPLATE_.Replace(self._TemplateDict)
        FileName = self.getMakefileName()
        if not os.path.exists(os.path.join(self._AutoGenObject.MakeFileDir, "deps.txt")):
            with open(os.path.join(self._AutoGenObject.MakeFileDir, "deps.txt"),"w+") as fd:
                fd.write("")
        if not os.path.exists(os.path.join(self._AutoGenObject.MakeFileDir, "dependency")):
            with open(os.path.join(self._AutoGenObject.MakeFileDir, "dependency"),"w+") as fd:
                fd.write("")
        if not os.path.exists(os.path.join(self._AutoGenObject.MakeFileDir, "deps_target")):
            with open(os.path.join(self._AutoGenObject.MakeFileDir, "deps_target"),"w+") as fd:
                fd.write("")
        return SaveFileOnChange(os.path.join(self._AutoGenObject.MakeFileDir, FileName), FileContent, False)

    ## 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._Platform] % {'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._Platform] % {'dir':Dir} for Dir in DirList]

    def PlaceMacro(self, Path, MacroDefinitions=None):
        if Path.startswith("$("):
            return Path
        else:
            if MacroDefinitions is None:
                MacroDefinitions = {}
            PathLength = len(Path)
            for MacroName in MacroDefinitions:
                MacroValue = MacroDefinitions[MacroName]
                MacroValueLength = len(MacroValue)
                if MacroValueLength == 0:
                    continue
                if MacroValueLength <= PathLength and Path.startswith(MacroValue):
                    Path = "$(%s)%s" % (MacroName, Path[MacroValueLength:])
                    break
            return Path

## 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_ = TemplateString('''\
${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 = ${platform_dir}
PLATFORM_OUTPUT_DIR = ${platform_output_directory}

#
# Module Macro Definition
#
MODULE_NAME = ${module_name}
MODULE_GUID = ${module_guid}
MODULE_NAME_GUID = ${module_name_guid}
MODULE_VERSION = ${module_version}
MODULE_TYPE = ${module_type}
MODULE_FILE = ${module_file}
MODULE_FILE_BASE_NAME = ${module_file_base_name}
BASE_NAME = $(MODULE_NAME)
MODULE_RELATIVE_DIR = ${module_relative_directory}
PACKAGE_RELATIVE_DIR = ${package_relative_directory}
MODULE_DIR = ${module_dir}
FFS_OUTPUT_DIR = ${ffs_output_directory}

MODULE_ENTRY_POINT = ${module_entry_point}
ARCH_ENTRY_POINT = ${arch_entry_point}
IMAGE_ENTRY_POINT = ${image_entry_point}

${BEGIN}${module_extra_defines}
${END}
#
# Build Configuration Macro Definition
#
ARCH = ${architecture}
TOOLCHAIN = ${toolchain_tag}
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 = ${module_build_directory}
OUTPUT_DIR = ${module_output_directory}
DEBUG_DIR = ${module_debug_directory}
DEST_DIR_OUTPUT = $(OUTPUT_DIR)
DEST_DIR_DEBUG = $(DEBUG_DIR)

#
# Shell Command Macro
#
${BEGIN}${shell_command_code} = ${shell_command}
${END}

#
# Tools definitions specific to this module
#
${BEGIN}${module_tool_definitions}
${END}
MAKE_FILE = ${makefile_path}

#
# Build Macro
#
${BEGIN}${file_macro}
${END}

#
# Overridable Target Macro Definitions
#
FORCE_REBUILD = force_build
INIT_TARGET = init
PCH_TARGET =
BC_TARGET = ${BEGIN}${backward_compatible_target} ${END}
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) $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET)

#
# ModuleTarget
#

mbuild: $(INIT_TARGET) $(BC_TARGET) gen_libs $(PCH_TARGET) $(CODA_TARGET)

#
# Build Target used in multi-thread build mode, which will bypass the init and gen_libs targets
#

tbuild: $(BC_TARGET) $(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: info dirs

info:
\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)]

dirs:
${BEGIN}\t-@${create_directory_command}\n${END}

strdefs:
\t-@$(CP) $(DEBUG_DIR)${separator}AutoGen.h $(DEBUG_DIR)${separator}$(MODULE_NAME)StrDefs.h

#
# GenLibsTarget
#
gen_libs:
\t${BEGIN}@"$(MAKE)" $(MAKE_FLAGS) -f ${dependent_library_build_directory}${separator}${makefile_name}
\t${END}@cd $(MODULE_BUILD_DIR)

#
# Build Flash Device Image
#
gen_fds:
\t@"$(MAKE)" $(MAKE_FLAGS) -f $(BUILD_DIR)${separator}${makefile_name} fds
\t@cd $(MODULE_BUILD_DIR)

${INCLUDETAG}

#
# Individual Object Build Targets
#
${BEGIN}${file_build_target}
${END}

#
# clean all intermediate files
#
clean:
\t${BEGIN}${clean_command}
\t${END}\t$(RM) AutoGenTimeStamp

#
# 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
\t$(RM) AutoGenTimeStamp

#
# clean all dependent libraries built
#
cleanlib:
\t${BEGIN}-@${library_build_command} cleanall
\t${END}@cd $(MODULE_BUILD_DIR)\n\n''')

    _FILE_MACRO_TEMPLATE = TemplateString("${macro_name} = ${BEGIN} \\\n    ${source_file}${END}\n")
    _BUILD_TARGET_TEMPLATE = TemplateString("${BEGIN}${target} : ${deps}\n${END}\t${cmd}\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.FileBuildTargetList = []       # [(src, target string)]
        self.BuildTargetList = []           # [target string]
        self.PendingBuildTargetList = []    # [FileBuildRule objects]
        self.CommonFileDependency = []
        self.FileListMacros = {}
        self.ListFileMacros = {}
        self.ObjTargetDict = OrderedDict()
        self.FileCache = {}
        self.LibraryBuildCommandList = []
        self.LibraryFileList = []
        self.LibraryMakefileList = []
        self.LibraryBuildDirectoryList = []
        self.SystemLibraryList = []
        self.Macros = OrderedDict()
        self.Macros["OUTPUT_DIR"      ] = self._AutoGenObject.Macros["OUTPUT_DIR"]
        self.Macros["DEBUG_DIR"       ] = self._AutoGenObject.Macros["DEBUG_DIR"]
        self.Macros["MODULE_BUILD_DIR"] = self._AutoGenObject.Macros["MODULE_BUILD_DIR"]
        self.Macros["BIN_DIR"         ] = self._AutoGenObject.Macros["BIN_DIR"]
        self.Macros["BUILD_DIR"       ] = self._AutoGenObject.Macros["BUILD_DIR"]
        self.Macros["WORKSPACE"       ] = self._AutoGenObject.Macros["WORKSPACE"]
        self.Macros["FFS_OUTPUT_DIR"  ] = self._AutoGenObject.Macros["FFS_OUTPUT_DIR"]
        self.GenFfsList                 = ModuleAutoGen.GenFfsList
        self.MacroList = ['FFS_OUTPUT_DIR', 'MODULE_GUID', 'OUTPUT_DIR']
        self.FfsOutputFileList = []
        self.DependencyHeaderFileSet = set()

    # Compose a dict object containing information used to do replacement in template
    @property
    def _TemplateDict(self):
        MyAgo = self._AutoGenObject
        Separator = self._SEP_[self._Platform]

        # break build if no source files and binary files are found
        if len(MyAgo.SourceFileList) == 0 and len(MyAgo.BinaryFileList) == 0:
            EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"
                            % (MyAgo.BuildTarget, MyAgo.ToolChain, MyAgo.Arch),
                            ExtraData="[%s]" % str(MyAgo))

        # convert dependent libraries to build command
        self.ProcessDependentLibrary()
        if len(MyAgo.Module.ModuleEntryPointList) > 0:
            ModuleEntryPoint = MyAgo.Module.ModuleEntryPointList[0]
        else:
            ModuleEntryPoint = "_ModuleEntryPoint"

        ArchEntryPoint = ModuleEntryPoint

        if MyAgo.Arch == "EBC":
            # EBC compiler always use "EfiStart" as entry point. Only applies to EdkII modules
            ImageEntryPoint = "EfiStart"
        else:
            # EdkII modules always use "_ModuleEntryPoint" as entry point
            ImageEntryPoint = "_ModuleEntryPoint"

        for k, v in MyAgo.Module.Defines.items():
            if k not in MyAgo.Macros:
                MyAgo.Macros[k] = v

        if 'MODULE_ENTRY_POINT' not in MyAgo.Macros:
            MyAgo.Macros['MODULE_ENTRY_POINT'] = ModuleEntryPoint
        if 'ARCH_ENTRY_POINT' not in MyAgo.Macros:
            MyAgo.Macros['ARCH_ENTRY_POINT'] = ArchEntryPoint
        if 'IMAGE_ENTRY_POINT' not in MyAgo.Macros:
            MyAgo.Macros['IMAGE_ENTRY_POINT'] = ImageEntryPoint

        PCI_COMPRESS_Flag = False
        for k, v in MyAgo.Module.Defines.items():
            if 'PCI_COMPRESS' == k and 'TRUE' == v:
                PCI_COMPRESS_Flag = True

        # tools definitions
        ToolsDef = []
        IncPrefix = self._INC_FLAG_[MyAgo.ToolChainFamily]
        for Tool in sorted(list(MyAgo.BuildOption)):
            Appended = False
            for Attr in sorted(list(MyAgo.BuildOption[Tool])):
                Value = MyAgo.BuildOption[Tool][Attr]
                if Attr == "FAMILY":
                    continue
                elif Attr == "PATH":
                    ToolsDef.append("%s = %s" % (Tool, Value))
                    Appended = True
                else:
                    # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.
                    if Tool == "MAKE":
                        continue
                    # Remove duplicated include path, if any
                    if Attr == "FLAGS":
                        Value = RemoveDupOption(Value, IncPrefix, MyAgo.IncludePathList)
                        if Tool == "OPTROM" and PCI_COMPRESS_Flag:
                            ValueList = Value.split()
                            if ValueList:
                                for i, v in enumerate(ValueList):
                                    if '-e' == v:
                                        ValueList[i] = '-ec'
                                Value = ' '.join(ValueList)

                    ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value))
                    Appended = True
            if Appended:
                ToolsDef.append("")

        # generate the Response file and Response flag
        RespDict = self.CommandExceedLimit()
        RespFileList = os.path.join(MyAgo.OutputDir, 'respfilelist.txt')
        if RespDict:
            RespFileListContent = ''
            for Resp in RespDict:
                RespFile = os.path.join(MyAgo.OutputDir, str(Resp).lower() + '.txt')
                StrList = RespDict[Resp].split(' ')
                UnexpandMacro = []
                NewStr = []
                for Str in StrList:
                    if '$' in Str or '-MMD' in Str or '-MF' in Str:
                        UnexpandMacro.append(Str)
                    else:
                        NewStr.append(Str)
                UnexpandMacroStr = ' '.join(UnexpandMacro)
                NewRespStr = ' '.join(NewStr)
                SaveFileOnChange(RespFile, NewRespStr, False)
                ToolsDef.append("%s = %s" % (Resp, UnexpandMacroStr + ' @' + RespFile))
                RespFileListContent += '@' + RespFile + TAB_LINE_BREAK
                RespFileListContent += NewRespStr + TAB_LINE_BREAK
            SaveFileOnChange(RespFileList, RespFileListContent, False)
        else:
            if os.path.exists(RespFileList):
                os.remove(RespFileList)

        # convert source files and binary files to build targets
        self.ResultFileList = [str(T.Target) for T in MyAgo.CodaTargetList]
        if len(self.ResultFileList) == 0 and len(MyAgo.SourceFileList) != 0:
            EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",
                            ExtraData="[%s]" % str(MyAgo))

        self.ProcessBuildTargetList(MyAgo.OutputDir, ToolsDef)
        self.ParserGenerateFfsCmd()

        # Generate macros used to represent input files
        FileMacroList = [] # macro name = file list
        for FileListMacro in self.FileListMacros:
            FileMacro = self._FILE_MACRO_TEMPLATE.Replace(
                                                    {
                                                        "macro_name"  : FileListMacro,
                                                        "source_file" : self.FileListMacros[FileListMacro]
                                                    }
                                                    )
            FileMacroList.append(FileMacro)

        # INC_LIST is special
        FileMacro = ""
        IncludePathList = []
        for P in  MyAgo.IncludePathList:
            IncludePathList.append(IncPrefix + self.PlaceMacro(P, self.Macros))
            if FileBuildRule.INC_LIST_MACRO in self.ListFileMacros:
                self.ListFileMacros[FileBuildRule.INC_LIST_MACRO].append(IncPrefix + P)
        FileMacro += self._FILE_MACRO_TEMPLATE.Replace(
                                                {
                                                    "macro_name"   : "INC",
                                                    "source_file" : IncludePathList
                                                }
                                                )
        FileMacroList.append(FileMacro)
        # Add support when compiling .nasm source files
        IncludePathList = []
        asmsource = [item for item in MyAgo.SourceFileList if item.File.upper().endswith((".NASM",".ASM",".NASMB","S"))]
        if asmsource:
            for P in  MyAgo.IncludePathList:
                IncludePath = self._INC_FLAG_['NASM'] + self.PlaceMacro(P, self.Macros)
                if IncludePath.endswith(os.sep):
                    IncludePath = IncludePath.rstrip(os.sep)
                # When compiling .nasm files, need to add a literal backslash at each path.
                # In nmake makfiles, a trailing literal backslash must be escaped with a caret ('^').
                # It is otherwise replaced with a space (' '). This is not necessary for GNU makfefiles.
                if P == MyAgo.IncludePathList[-1] and self._Platform == WIN32_PLATFORM and self._FileType == NMAKE_FILETYPE:
                    IncludePath = ''.join([IncludePath, '^', os.sep])
                else:
                    IncludePath = os.path.join(IncludePath, '')
                IncludePathList.append(IncludePath)
            FileMacroList.append(self._FILE_MACRO_TEMPLATE.Replace({"macro_name": "NASM_INC", "source_file": IncludePathList}))

        # Generate macros used to represent files containing list of input files
        for ListFileMacro in self.ListFileMacros:
            ListFileName = os.path.join(MyAgo.OutputDir, "%s.lst" % ListFileMacro.lower()[:len(ListFileMacro) - 5])
            FileMacroList.append("%s = %s" % (ListFileMacro, ListFileName))
            SaveFileOnChange(
                ListFileName,
                "\n".join(self.ListFileMacros[ListFileMacro]),
                False
                )

        # Generate objlist used to create .obj file
        for Type in self.ObjTargetDict:
            NewLine = ' '.join(list(self.ObjTargetDict[Type]))
            FileMacroList.append("OBJLIST_%s = %s" % (list(self.ObjTargetDict.keys()).index(Type), NewLine))

        BcTargetList = []

        MakefileName = self.getMakefileName()
        LibraryMakeCommandList = []
        for D in self.LibraryBuildDirectoryList:
            Command = self._MAKE_TEMPLATE_[self._Platform] % {"file":os.path.join(D, MakefileName)}
            LibraryMakeCommandList.append(Command)

        package_rel_dir = MyAgo.SourceDir
        current_dir = self.Macros["WORKSPACE"]
        found = False
        while not found and os.sep in package_rel_dir:
            index = package_rel_dir.index(os.sep)
            current_dir = mws.join(current_dir, package_rel_dir[:index])
            if os.path.exists(current_dir):
                for fl in os.listdir(current_dir):
                    if fl.endswith('.dec'):
                        found = True
                        break
            package_rel_dir = package_rel_dir[index + 1:]

        MakefileTemplateDict = {
            "makefile_header"           : self._FILE_HEADER_[self._FileType],
            "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
            "makefile_name"             : 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,
            "ffs_output_directory"      : MyAgo.Macros["FFS_OUTPUT_DIR"],
            "platform_dir"              : MyAgo.Macros["PLATFORM_DIR"],

            "module_name"               : MyAgo.Name,
            "module_guid"               : MyAgo.Guid,
            "module_name_guid"          : MyAgo.UniqueBaseName,
            "module_version"            : MyAgo.Version,
            "module_type"               : MyAgo.ModuleType,
            "module_file"               : MyAgo.MetaFile.Name,
            "module_file_base_name"     : MyAgo.MetaFile.BaseName,
            "module_relative_directory" : MyAgo.SourceDir,
            "module_dir"                : mws.join (self.Macros["WORKSPACE"], MyAgo.SourceDir),
            "package_relative_directory": package_rel_dir,
            "module_extra_defines"      : ["%s = %s" % (k, v) for k, v in MyAgo.Module.Defines.items()],

            "architecture"              : MyAgo.Arch,
            "toolchain_tag"             : MyAgo.ToolChain,
            "build_target"              : MyAgo.BuildTarget,

            "platform_build_directory"  : self.PlatformInfo.BuildDir,
            "module_build_directory"    : MyAgo.BuildDir,
            "module_output_directory"   : MyAgo.OutputDir,
            "module_debug_directory"    : MyAgo.DebugDir,

            "separator"                 : Separator,
            "module_tool_definitions"   : ToolsDef,

            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),

            "module_entry_point"        : ModuleEntryPoint,
            "image_entry_point"         : ImageEntryPoint,
            "arch_entry_point"          : ArchEntryPoint,
            "remaining_build_target"    : self.ResultFileList,
            "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,
            "library_build_command"     : LibraryMakeCommandList,
            "file_macro"                : FileMacroList,
            "file_build_target"         : self.BuildTargetList,
            "backward_compatible_target": BcTargetList,
            "INCLUDETAG"                   : "\n".join([self._INCLUDE_CMD_[self._FileType] + " " + os.path.join("$(MODULE_BUILD_DIR)","dependency"),
                                                              self._INCLUDE_CMD_[self._FileType] + " " + os.path.join("$(MODULE_BUILD_DIR)","deps_target")
                                                              ])
        }

        return MakefileTemplateDict

    def ParserGenerateFfsCmd(self):
        #Add Ffs cmd to self.BuildTargetList
        OutputFile = ''
        DepsFileList = []

        for Cmd in self.GenFfsList:
            if Cmd[2]:
                for CopyCmd in Cmd[2]:
                    Src, Dst = CopyCmd
                    Src = self.ReplaceMacro(Src)
                    Dst = self.ReplaceMacro(Dst)
                    if Dst not in self.ResultFileList:
                        self.ResultFileList.append(Dst)
                    if '%s :' %(Dst) not in self.BuildTargetList:
                        self.BuildTargetList.append("%s : %s" %(Dst,Src))
                        self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._Platform] %{'Src': Src, 'Dst': Dst})

            FfsCmdList = Cmd[0]
            for index, Str in enumerate(FfsCmdList):
                if '-o' == Str:
                    OutputFile = FfsCmdList[index + 1]
                if '-i' == Str or "-oi" == Str:
                    if DepsFileList == []:
                        DepsFileList = [FfsCmdList[index + 1]]
                    else:
                        DepsFileList.append(FfsCmdList[index + 1])
            DepsFileString = ' '.join(DepsFileList).strip()
            if DepsFileString == '':
                continue
            OutputFile = self.ReplaceMacro(OutputFile)
            self.ResultFileList.append(OutputFile)
            DepsFileString = self.ReplaceMacro(DepsFileString)
            self.BuildTargetList.append('%s : %s' % (OutputFile, DepsFileString))
            CmdString = ' '.join(FfsCmdList).strip()
            CmdString = self.ReplaceMacro(CmdString)
            self.BuildTargetList.append('\t%s' % CmdString)

            self.ParseSecCmd(DepsFileList, Cmd[1])
            for SecOutputFile, SecDepsFile, SecCmd in self.FfsOutputFileList :
                self.BuildTargetList.append('%s : %s' % (self.ReplaceMacro(SecOutputFile), self.ReplaceMacro(SecDepsFile)))
                self.BuildTargetList.append('\t%s' % self.ReplaceMacro(SecCmd))
            self.FfsOutputFileList = []

    def ParseSecCmd(self, OutputFileList, CmdTuple):
        for OutputFile in OutputFileList:
            for SecCmdStr in CmdTuple:
                SecDepsFileList = []
                SecCmdList = SecCmdStr.split()
                CmdName = SecCmdList[0]
                for index, CmdItem in enumerate(SecCmdList):
                    if '-o' == CmdItem and OutputFile == SecCmdList[index + 1]:
                        index = index + 1
                        while index + 1 < len(SecCmdList):
                            if not SecCmdList[index+1].startswith('-'):
                                SecDepsFileList.append(SecCmdList[index + 1])
                            index = index + 1
                        if CmdName == 'Trim':
                            SecDepsFileList.append(os.path.join('$(DEBUG_DIR)', os.path.basename(OutputFile).replace('offset', 'efi')))
                        if OutputFile.endswith('.ui') or OutputFile.endswith('.ver'):
                            SecDepsFileList.append(os.path.join('$(MODULE_DIR)', '$(MODULE_FILE)'))
                        self.FfsOutputFileList.append((OutputFile, ' '.join(SecDepsFileList), SecCmdStr))
                        if len(SecDepsFileList) > 0:
                            self.ParseSecCmd(SecDepsFileList, CmdTuple)
                        break
                    else:
                        continue

    def ReplaceMacro(self, str):
        for Macro in self.MacroList:
            if self._AutoGenObject.Macros[Macro] and os.path.normcase(self._AutoGenObject.Macros[Macro]) in os.path.normcase(str):
                replace_dir = str[os.path.normcase(str).index(os.path.normcase(self._AutoGenObject.Macros[Macro])): os.path.normcase(str).index(
                    os.path.normcase(self._AutoGenObject.Macros[Macro])) + len(self._AutoGenObject.Macros[Macro])]
                str = str.replace(replace_dir, '$(' + Macro + ')')
        return str

    def CommandExceedLimit(self):
        FlagDict = {
                    'CC'    :  { 'Macro' : '$(CC_FLAGS)',    'Value' : False},
                    'PP'    :  { 'Macro' : '$(PP_FLAGS)',    'Value' : False},
                    'APP'   :  { 'Macro' : '$(APP_FLAGS)',   'Value' : False},
                    'ASLPP' :  { 'Macro' : '$(ASLPP_FLAGS)', 'Value' : False},
                    'VFRPP' :  { 'Macro' : '$(VFRPP_FLAGS)', 'Value' : False},
                    'ASM'   :  { 'Macro' : '$(ASM_FLAGS)',   'Value' : False},
                    'ASLCC' :  { 'Macro' : '$(ASLCC_FLAGS)', 'Value' : False},
                   }

        RespDict = {}
        FileTypeList = []
        IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]

        # base on the source files to decide the file type
        for File in self._AutoGenObject.SourceFileList:
            for type in self._AutoGenObject.FileTypes:
                if File in self._AutoGenObject.FileTypes[type]:
                    if type not in FileTypeList:
                        FileTypeList.append(type)

        # calculate the command-line length
        if FileTypeList:
            for type in FileTypeList:
                BuildTargets = self._AutoGenObject.BuildRules[type].BuildTargets
                for Target in BuildTargets:
                    CommandList = BuildTargets[Target].Commands
                    for SingleCommand in CommandList:
                        Tool = ''
                        SingleCommandLength = len(SingleCommand)
                        SingleCommandList = SingleCommand.split()
                        if len(SingleCommandList) > 0:
                            for Flag in FlagDict:
                                if '$('+ Flag +')' in SingleCommandList[0]:
                                    Tool = Flag
                                    break
                        if Tool:
                            if 'PATH' not in self._AutoGenObject.BuildOption[Tool]:
                                EdkLogger.error("build", AUTOGEN_ERROR, "%s_PATH doesn't exist in %s ToolChain and %s Arch." %(Tool, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch), ExtraData="[%s]" % str(self._AutoGenObject))
                            SingleCommandLength += len(self._AutoGenObject.BuildOption[Tool]['PATH'])
                            for item in SingleCommandList[1:]:
                                if FlagDict[Tool]['Macro'] in item:
                                    if 'FLAGS' not in self._AutoGenObject.BuildOption[Tool]:
                                        EdkLogger.error("build", AUTOGEN_ERROR, "%s_FLAGS doesn't exist in %s ToolChain and %s Arch." %(Tool, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch), ExtraData="[%s]" % str(self._AutoGenObject))
                                    Str = self._AutoGenObject.BuildOption[Tool]['FLAGS']
                                    for Option in self._AutoGenObject.BuildOption:
                                        for Attr in self._AutoGenObject.BuildOption[Option]:
                                            if Str.find(Option + '_' + Attr) != -1:
                                                Str = Str.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])
                                    while(Str.find('$(') != -1):
                                        for macro in self._AutoGenObject.Macros:
                                            MacroName = '$('+ macro + ')'
                                            if (Str.find(MacroName) != -1):
                                                Str = Str.replace(MacroName, self._AutoGenObject.Macros[macro])
                                                break
                                        else:
                                            break
                                    SingleCommandLength += len(Str)
                                elif '$(INC)' in item:
                                    SingleCommandLength += self._AutoGenObject.IncludePathLength + len(IncPrefix) * len(self._AutoGenObject.IncludePathList)
                                elif item.find('$(') != -1:
                                    Str = item
                                    for Option in self._AutoGenObject.BuildOption:
                                        for Attr in self._AutoGenObject.BuildOption[Option]:
                                            if Str.find(Option + '_' + Attr) != -1:
                                                Str = Str.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])
                                    while(Str.find('$(') != -1):
                                        for macro in self._AutoGenObject.Macros:
                                            MacroName = '$('+ macro + ')'
                                            if (Str.find(MacroName) != -1):
                                                Str = Str.replace(MacroName, self._AutoGenObject.Macros[macro])
                                                break
                                        else:
                                            break
                                    SingleCommandLength += len(Str)

                            if SingleCommandLength > GlobalData.gCommandMaxLength:
                                FlagDict[Tool]['Value'] = True

                # generate the response file content by combine the FLAGS and INC
                for Flag in FlagDict:
                    if FlagDict[Flag]['Value']:
                        Key = Flag + '_RESP'
                        RespMacro = FlagDict[Flag]['Macro'].replace('FLAGS', 'RESP')
                        Value = self._AutoGenObject.BuildOption[Flag]['FLAGS']
                        for inc in self._AutoGenObject.IncludePathList:
                            Value += ' ' + IncPrefix + inc
                        for Option in self._AutoGenObject.BuildOption:
                            for Attr in self._AutoGenObject.BuildOption[Option]:
                                if Value.find(Option + '_' + Attr) != -1:
                                    Value = Value.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])
                        while (Value.find('$(') != -1):
                            for macro in self._AutoGenObject.Macros:
                                MacroName = '$('+ macro + ')'
                                if (Value.find(MacroName) != -1):
                                    Value = Value.replace(MacroName, self._AutoGenObject.Macros[macro])
                                    break
                            else:
                                break

                        if self._AutoGenObject.ToolChainFamily == 'GCC':
                            #
                            # Replace '\' with '/' in the response file.
                            # Skip content within "" or \"\"
                            #
                            ValueList = re.split(r'("|\\"|\s+)', Value)
                            Skip = False
                            for i, v in enumerate(ValueList):
                                if v in ('"', '\\"'):
                                    Skip = not Skip
                                elif not Skip:
                                    ValueList[i] = v.replace('\\', '/')
                            Value = ''.join(ValueList)
                        RespDict[Key] = Value

                        for Target in BuildTargets:
                            for i, SingleCommand in enumerate(BuildTargets[Target].Commands):
                                if FlagDict[Flag]['Macro'] in SingleCommand:
                                    BuildTargets[Target].Commands[i] = SingleCommand.replace('$(INC)', '').replace(FlagDict[Flag]['Macro'], RespMacro)
        return RespDict

    def ProcessBuildTargetList(self, RespFile, ToolsDef):
        #
        # Search dependency file list for each source file
        #
        ForceIncludedFile = []
        for File in self._AutoGenObject.AutoGenFileList:
            if File.Ext == '.h':
                ForceIncludedFile.append(File)
        SourceFileList = []
        OutPutFileList = []
        for Target in self._AutoGenObject.IntroTargetList:
            SourceFileList.extend(Target.Inputs)
            OutPutFileList.extend(Target.Outputs)

        if OutPutFileList:
            for Item in OutPutFileList:
                if Item in SourceFileList:
                    SourceFileList.remove(Item)

        FileDependencyDict = {item:ForceIncludedFile for item in SourceFileList}

        for Dependency in FileDependencyDict.values():
            self.DependencyHeaderFileSet.update(set(Dependency))

        # Get a set of unique package includes from MetaFile
        parentMetaFileIncludes = set()
        for aInclude in self._AutoGenObject.PackageIncludePathList:
            aIncludeName = str(aInclude)
            parentMetaFileIncludes.add(aIncludeName.lower())

        # Check if header files are listed in metafile
        # Get a set of unique module header source files from MetaFile
        headerFilesInMetaFileSet = set()
        for aFile in self._AutoGenObject.SourceFileList:
            aFileName = str(aFile)
            if not aFileName.endswith('.h'):
                continue
            headerFilesInMetaFileSet.add(aFileName.lower())

        # Get a set of unique module autogen files
        localAutoGenFileSet = set()
        for aFile in self._AutoGenObject.AutoGenFileList:
            localAutoGenFileSet.add(str(aFile).lower())

        # Get a set of unique module dependency header files
        # Exclude autogen files and files not in the source directory
        # and files that are under the package include list
        headerFileDependencySet = set()
        localSourceDir = str(self._AutoGenObject.SourceDir).lower()
        for Dependency in FileDependencyDict.values():
            for aFile in Dependency:
                aFileName = str(aFile).lower()
                # Exclude non-header files
                if not aFileName.endswith('.h'):
                    continue
                # Exclude autogen files
                if aFileName in localAutoGenFileSet:
                    continue
                # Exclude include out of local scope
                if localSourceDir not in aFileName:
                    continue
                # Exclude files covered by package includes
                pathNeeded = True
                for aIncludePath in parentMetaFileIncludes:
                    if aIncludePath in aFileName:
                        pathNeeded = False
                        break
                if not pathNeeded:
                    continue
                # Keep the file to be checked
                headerFileDependencySet.add(aFileName)

        # Check if a module dependency header file is missing from the module's MetaFile
        for aFile in headerFileDependencySet:
            if aFile in headerFilesInMetaFileSet:
                continue
            if GlobalData.gUseHashCache:
                GlobalData.gModuleBuildTracking[self._AutoGenObject] = 'FAIL_METAFILE'
            EdkLogger.warn("build","Module MetaFile [Sources] is missing local header!",
                        ExtraData = "Local Header: " + aFile + " not found in " + self._AutoGenObject.MetaFile.Path
                        )

        for File,Dependency in FileDependencyDict.items():
            if not Dependency:
                continue

            self._AutoGenObject.AutoGenDepSet |= set(Dependency)

        CmdSumDict = {}
        CmdTargetDict = {}
        CmdCppDict = {}
        DependencyDict = FileDependencyDict.copy()

        # Convert target description object to target string in makefile
        if self._AutoGenObject.BuildRuleFamily == TAB_COMPILER_MSFT and TAB_C_CODE_FILE in self._AutoGenObject.Targets:
            for T in self._AutoGenObject.Targets[TAB_C_CODE_FILE]:
                NewFile = self.PlaceMacro(str(T), self.Macros)
                if not self.ObjTargetDict.get(T.Target.SubDir):
                    self.ObjTargetDict[T.Target.SubDir] = set()
                self.ObjTargetDict[T.Target.SubDir].add(NewFile)
        for Type in self._AutoGenObject.Targets:
            resp_file_number = 0
            for T in self._AutoGenObject.Targets[Type]:
                # Generate related macros if needed
                if T.GenFileListMacro and T.FileListMacro not in self.FileListMacros:
                    self.FileListMacros[T.FileListMacro] = []
                if T.GenListFile and T.ListFileMacro not in self.ListFileMacros:
                    self.ListFileMacros[T.ListFileMacro] = []
                if T.GenIncListFile and T.IncListFileMacro not in self.ListFileMacros:
                    self.ListFileMacros[T.IncListFileMacro] = []

                Deps = []
                CCodeDeps = []
                # Add force-dependencies
                for Dep in T.Dependencies:
                    Deps.append(self.PlaceMacro(str(Dep), self.Macros))
                    if Dep != '$(MAKE_FILE)':
                        CCodeDeps.append(self.PlaceMacro(str(Dep), self.Macros))
                # Add inclusion-dependencies
                if len(T.Inputs) == 1 and T.Inputs[0] in FileDependencyDict:
                    for F in FileDependencyDict[T.Inputs[0]]:
                        Deps.append(self.PlaceMacro(str(F), self.Macros))
                # Add source-dependencies
                for F in T.Inputs:
                    NewFile = self.PlaceMacro(str(F), self.Macros)
                    # In order to use file list macro as dependency
                    if T.GenListFile:
                        # gnu tools need forward slash path separator, even on Windows
                        self.ListFileMacros[T.ListFileMacro].append(str(F).replace ('\\', '/'))
                        self.FileListMacros[T.FileListMacro].append(NewFile)
                    elif T.GenFileListMacro:
                        self.FileListMacros[T.FileListMacro].append(NewFile)
                    else:
                        Deps.append(NewFile)
                for key in self.FileListMacros:
                    self.FileListMacros[key].sort()
                # Use file list macro as dependency
                if T.GenFileListMacro:
                    Deps.append("$(%s)" % T.FileListMacro)
                    if Type in [TAB_OBJECT_FILE, TAB_STATIC_LIBRARY]:
                        Deps.append("$(%s)" % T.ListFileMacro)

                if self._AutoGenObject.BuildRuleFamily == TAB_COMPILER_MSFT and Type == TAB_C_CODE_FILE:
                    T, CmdTarget, CmdTargetDict, CmdCppDict = self.ParserCCodeFile(T, Type, CmdSumDict, CmdTargetDict,
                                                                                   CmdCppDict, DependencyDict, RespFile,
                                                                                   ToolsDef, resp_file_number)
                    resp_file_number += 1
                    TargetDict = {"target": self.PlaceMacro(T.Target.Path, self.Macros), "cmd": "\n\t".join(T.Commands),"deps": CCodeDeps}
                    CmdLine = self._BUILD_TARGET_TEMPLATE.Replace(TargetDict).rstrip().replace('\t$(OBJLIST', '$(OBJLIST')
                    if T.Commands:
                        CmdLine = '%s%s' %(CmdLine, TAB_LINE_BREAK)
                    if CCodeDeps or CmdLine:
                        self.BuildTargetList.append(CmdLine)
                else:
                    TargetDict = {"target": self.PlaceMacro(T.Target.Path, self.Macros), "cmd": "\n\t".join(T.Commands),"deps": Deps}
                    self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(TargetDict))

                    # Add a Makefile rule for targets generating multiple files.
                    # The main output is a prerequisite for the other output files.
                    for i in T.Outputs[1:]:
                        AnnexeTargetDict = {"target": self.PlaceMacro(i.Path, self.Macros), "cmd": "", "deps": self.PlaceMacro(T.Target.Path, self.Macros)}
                        self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(AnnexeTargetDict))

    def ParserCCodeFile(self, T, Type, CmdSumDict, CmdTargetDict, CmdCppDict, DependencyDict, RespFile, ToolsDef,
                            resp_file_number):
        SaveFilePath = os.path.join(RespFile, "cc_resp_%s.txt" % resp_file_number)
        if not CmdSumDict:
            for item in self._AutoGenObject.Targets[Type]:
                CmdSumDict[item.Target.SubDir] = item.Target.BaseName
                for CppPath in item.Inputs:
                    Path = self.PlaceMacro(CppPath.Path, self.Macros)
                    if CmdCppDict.get(item.Target.SubDir):
                        CmdCppDict[item.Target.SubDir].append(Path)
                    else:
                        CmdCppDict[item.Target.SubDir] = ['$(MAKE_FILE)', Path]
                    if CppPath.Path in DependencyDict:
                        for Temp in DependencyDict[CppPath.Path]:
                            try:
                                Path = self.PlaceMacro(Temp.Path, self.Macros)
                            except:
                                continue
                            if Path not in (self.CommonFileDependency + CmdCppDict[item.Target.SubDir]):
                                CmdCppDict[item.Target.SubDir].append(Path)
        if T.Commands:
            CommandList = T.Commands[:]
            for Item in CommandList[:]:
                SingleCommandList = Item.split()
                if len(SingleCommandList) > 0 and self.CheckCCCmd(SingleCommandList):
                    for Temp in SingleCommandList:
                        if Temp.startswith('/Fo'):
                            CmdSign = '%s%s' % (Temp.rsplit(TAB_SLASH, 1)[0], TAB_SLASH)
                            break
                    else:
                        continue
                    if CmdSign not in list(CmdTargetDict.keys()):
                        cmd = Item.replace(Temp, CmdSign)
                        if SingleCommandList[-1] in cmd:
                            CmdTargetDict[CmdSign] = [cmd.replace(SingleCommandList[-1], "").rstrip(), SingleCommandList[-1]]
                    else:
                        # CmdTargetDict[CmdSign] = "%s %s" % (CmdTargetDict[CmdSign], SingleCommandList[-1])
                        CmdTargetDict[CmdSign].append(SingleCommandList[-1])
                    Index = CommandList.index(Item)
                    CommandList.pop(Index)
                    BaseName = SingleCommandList[-1].rsplit('.',1)[0]
                    if BaseName.endswith("%s%s" % (TAB_SLASH, CmdSumDict[CmdSign[3:].rsplit(TAB_SLASH, 1)[0]])):
                        Cpplist = CmdCppDict[T.Target.SubDir]
                        Cpplist.insert(0, '$(OBJLIST_%d): ' % list(self.ObjTargetDict.keys()).index(T.Target.SubDir))
                        source_files = CmdTargetDict[CmdSign][1:]
                        source_files.insert(0, " ")
                        if len(source_files)>2:
                            SaveFileOnChange(SaveFilePath, " ".join(source_files), False)
                            T.Commands[Index] = '%s\n\t%s $(cc_resp_%s)' % (
                            ' \\\n\t'.join(Cpplist), CmdTargetDict[CmdSign][0], resp_file_number)
                            ToolsDef.append("cc_resp_%s = @%s" % (resp_file_number, SaveFilePath))

                        elif len(source_files)<=2 and len(" ".join(CmdTargetDict[CmdSign][:2]))>GlobalData.gCommandMaxLength:
                            SaveFileOnChange(SaveFilePath, " ".join(source_files), False)
                            T.Commands[Index] = '%s\n\t%s $(cc_resp_%s)' % (
                                ' \\\n\t'.join(Cpplist), CmdTargetDict[CmdSign][0], resp_file_number)
                            ToolsDef.append("cc_resp_%s = @%s" % (resp_file_number, SaveFilePath))

                        else:
                            T.Commands[Index] = '%s\n\t%s' % (' \\\n\t'.join(Cpplist), " ".join(CmdTargetDict[CmdSign]))
                    else:
                        T.Commands.pop(Index)
        return T, CmdSumDict, CmdTargetDict, CmdCppDict

    def CheckCCCmd(self, CommandList):
        for cmd in CommandList:
            if '$(CC)' in cmd:
                return True
        return False
    ## For creating makefile targets for dependent libraries
    def ProcessDependentLibrary(self):
        for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
            if not LibraryAutoGen.IsBinaryModule:
                self.LibraryBuildDirectoryList.append(self.PlaceMacro(LibraryAutoGen.BuildDir, self.Macros))

    ## 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] = GetDependencyList(self._AutoGenObject, self.FileCache, F, ForceInculeList, SearchPathList)
        return Dependency


## 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_ = TemplateString('''\
${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 = ${platform_dir}
PLATFORM_OUTPUT_DIR = ${platform_output_directory}

#
# Module Macro Definition
#
MODULE_NAME = ${module_name}
MODULE_GUID = ${module_guid}
MODULE_NAME_GUID = ${module_name_guid}
MODULE_VERSION = ${module_version}
MODULE_TYPE = ${module_type}
MODULE_FILE = ${module_file}
MODULE_FILE_BASE_NAME = ${module_file_base_name}
BASE_NAME = $(MODULE_NAME)
MODULE_RELATIVE_DIR = ${module_relative_directory}
MODULE_DIR = ${module_dir}

#
# Build Configuration Macro Definition
#
ARCH = ${architecture}
TOOLCHAIN = ${toolchain_tag}
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 = ${module_build_directory}
OUTPUT_DIR = ${module_output_directory}
DEBUG_DIR = ${module_debug_directory}
DEST_DIR_OUTPUT = $(OUTPUT_DIR)
DEST_DIR_DEBUG = $(DEBUG_DIR)

#
# Tools definitions specific to this module
#
${BEGIN}${module_tool_definitions}
${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

#
# Build Target used in multi-thread build mode, which no init target is needed
#

tbuild: all

#
# Initialization target: print build information and create necessary directories
#
init:
\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(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)"]
        self.DependencyHeaderFileSet = set()

    # Compose a dict object containing information used to do replacement in template
    @property
    def _TemplateDict(self):
        Separator = self._SEP_[self._Platform]
        MyAgo = self._AutoGenObject
        if self._FileType not in MyAgo.CustomMakefile:
            EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,
                            ExtraData="[%s]" % str(MyAgo))
        MakefilePath = mws.join(
                                MyAgo.WorkspaceDir,
                                MyAgo.CustomMakefile[self._FileType]
                                )
        try:
            CustomMakefile = open(MakefilePath, 'r').read()
        except:
            EdkLogger.error('build', FILE_OPEN_FAILURE, File=str(MyAgo),
                            ExtraData=MyAgo.CustomMakefile[self._FileType])

        # tools definitions
        ToolsDef = []
        for Tool in MyAgo.BuildOption:
            # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.
            if Tool == "MAKE":
                continue
            for Attr in MyAgo.BuildOption[Tool]:
                if Attr == "FAMILY":
                    continue
                elif Attr == "PATH":
                    ToolsDef.append("%s = %s" % (Tool, MyAgo.BuildOption[Tool][Attr]))
                else:
                    ToolsDef.append("%s_%s = %s" % (Tool, Attr, MyAgo.BuildOption[Tool][Attr]))
            ToolsDef.append("")

        MakefileName = self.getMakefileName()
        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,
            "platform_dir"              : MyAgo.Macros["PLATFORM_DIR"],

            "module_name"               : MyAgo.Name,
            "module_guid"               : MyAgo.Guid,
            "module_name_guid"          : MyAgo.UniqueBaseName,
            "module_version"            : MyAgo.Version,
            "module_type"               : MyAgo.ModuleType,
            "module_file"               : MyAgo.MetaFile,
            "module_file_base_name"     : MyAgo.MetaFile.BaseName,
            "module_relative_directory" : MyAgo.SourceDir,
            "module_dir"                : mws.join (MyAgo.WorkspaceDir, MyAgo.SourceDir),

            "architecture"              : MyAgo.Arch,
            "toolchain_tag"             : MyAgo.ToolChain,
            "build_target"              : MyAgo.BuildTarget,

            "platform_build_directory"  : self.PlatformInfo.BuildDir,
            "module_build_directory"    : MyAgo.BuildDir,
            "module_output_directory"   : MyAgo.OutputDir,
            "module_debug_directory"    : MyAgo.DebugDir,

            "separator"                 : Separator,
            "module_tool_definitions"   : ToolsDef,

            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),

            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
            "custom_makefile_content"   : CustomMakefile
        }

        return MakefileTemplateDict

## 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_ = TemplateString('''\
${makefile_header}

#
# Platform Macro Definition
#
PLATFORM_NAME = ${platform_name}
PLATFORM_GUID = ${platform_guid}
PLATFORM_VERSION = ${platform_version}
PLATFORM_FILE = ${platform_file}
PLATFORM_DIR = ${platform_dir}
PLATFORM_OUTPUT_DIR = ${platform_output_directory}

#
# Build Configuration Macro Definition
#
TOOLCHAIN = ${toolchain_tag}
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_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_FILE) [${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@"$(MAKE)" $(MAKE_FLAGS) -f ${library_makefile_list} pbuild
${END}\t@cd $(BUILD_DIR)

#
# Build all modules:
#
build_modules:
${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${module_makefile_list} pbuild
${END}\t@cd $(BUILD_DIR)

#
# Clean intermediate files
#
clean:
\t${BEGIN}-@${library_build_command} clean
\t${END}${BEGIN}-@${module_build_command} 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}-@${library_build_command} 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 = []
        self.LibraryMakeCommandList = []
        self.DependencyHeaderFileSet = set()

    # Compose a dict object containing information used to do replacement in template
    @property
    def _TemplateDict(self):
        Separator = self._SEP_[self._Platform]

        MyAgo = self._AutoGenObject
        if "MAKE" not in MyAgo.ToolDefinition or "PATH" not in MyAgo.ToolDefinition["MAKE"]:
            EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",
                            ExtraData="[%s]" % str(MyAgo))

        self.IntermediateDirectoryList = ["$(BUILD_DIR)"]
        self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()
        self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()

        MakefileName = self.getMakefileName()
        LibraryMakefileList = []
        LibraryMakeCommandList = []
        for D in self.LibraryBuildDirectoryList:
            D = self.PlaceMacro(D, {"BUILD_DIR":MyAgo.BuildDir})
            Makefile = os.path.join(D, MakefileName)
            Command = self._MAKE_TEMPLATE_[self._Platform] % {"file":Makefile}
            LibraryMakefileList.append(Makefile)
            LibraryMakeCommandList.append(Command)
        self.LibraryMakeCommandList = LibraryMakeCommandList

        ModuleMakefileList = []
        ModuleMakeCommandList = []
        for D in self.ModuleBuildDirectoryList:
            D = self.PlaceMacro(D, {"BUILD_DIR":MyAgo.BuildDir})
            Makefile = os.path.join(D, MakefileName)
            Command = self._MAKE_TEMPLATE_[self._Platform] % {"file":Makefile}
            ModuleMakefileList.append(Makefile)
            ModuleMakeCommandList.append(Command)

        MakefileTemplateDict = {
            "makefile_header"           : self._FILE_HEADER_[self._FileType],
            "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),
            "make_path"                 : MyAgo.ToolDefinition["MAKE"]["PATH"],
            "makefile_name"             : MakefileName,
            "platform_name"             : MyAgo.Name,
            "platform_guid"             : MyAgo.Guid,
            "platform_version"          : MyAgo.Version,
            "platform_file"             : MyAgo.MetaFile,
            "platform_relative_directory": MyAgo.SourceDir,
            "platform_output_directory" : MyAgo.OutputDir,
            "platform_build_directory"  : MyAgo.BuildDir,
            "platform_dir"              : MyAgo.Macros["PLATFORM_DIR"],

            "toolchain_tag"             : MyAgo.ToolChain,
            "build_target"              : MyAgo.BuildTarget,
            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
            "build_architecture_list"   : MyAgo.Arch,
            "architecture"              : MyAgo.Arch,
            "separator"                 : Separator,
            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
            "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),
            "library_makefile_list"     : LibraryMakefileList,
            "module_makefile_list"      : ModuleMakefileList,
            "library_build_command"     : LibraryMakeCommandList,
            "module_build_command"      : ModuleMakeCommandList,
        }

        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:
            if not ModuleAutoGen.IsBinaryModule:
                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:
            if not LibraryAutoGen.IsBinaryModule:
                DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
        return DirList

## 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_ = TemplateString('''${BEGIN}\tGenFds -f ${fdf_file} --conf=${conf_directory} -o ${platform_build_directory} -t ${toolchain_tag} -b ${build_target} -p ${active_platform} -a ${build_architecture_list} ${extra_options}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -C ${cap} ${END}${BEGIN} -D ${macro} ${END}''')

    ## Constructor of TopLevelMakefile
    #
    #   @param  Workspace   Object of WorkspaceAutoGen class
    #
    def __init__(self, Workspace):
        BuildFile.__init__(self, Workspace)
        self.IntermediateDirectoryList = []
        self.DependencyHeaderFileSet = set()

    # Compose a dict object containing information used to do replacement in template
    @property
    def _TemplateDict(self):
        Separator = self._SEP_[self._Platform]

        # any platform autogen object is ok because we just need common information
        MyAgo = self._AutoGenObject

        if "MAKE" not in MyAgo.ToolDefinition or "PATH" not in MyAgo.ToolDefinition["MAKE"]:
            EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",
                            ExtraData="[%s]" % str(MyAgo))

        for Arch in MyAgo.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 MyAgo.FdfFile is not None and MyAgo.FdfFile != "":
            FdfFileList = [MyAgo.FdfFile]
            # macros passed to GenFds
            MacroDict = {}
            MacroDict.update(GlobalData.gGlobalDefines)
            MacroDict.update(GlobalData.gCommandLineDefines)
            for MacroName in MacroDict:
                if MacroDict[MacroName] != "":
                    MacroList.append('"%s=%s"' % (MacroName, MacroDict[MacroName].replace('\\', '\\\\')))
                else:
                    MacroList.append('"%s"' % MacroName)
        else:
            FdfFileList = []

        # pass extra common options to external program called in makefile, currently GenFds.exe
        ExtraOption = ''
        LogLevel = EdkLogger.GetLevel()
        if LogLevel == EdkLogger.VERBOSE:
            ExtraOption += " -v"
        elif LogLevel <= EdkLogger.DEBUG_9:
            ExtraOption += " -d %d" % (LogLevel - 1)
        elif LogLevel == EdkLogger.QUIET:
            ExtraOption += " -q"

        if GlobalData.gCaseInsensitive:
            ExtraOption += " -c"
        if not GlobalData.gEnableGenfdsMultiThread:
            ExtraOption += " --no-genfds-multi-thread"
        if GlobalData.gIgnoreSource:
            ExtraOption += " --ignore-sources"

        for pcd in GlobalData.BuildOptionPcd:
            if pcd[2]:
                pcdname = '.'.join(pcd[0:3])
            else:
                pcdname = '.'.join(pcd[0:2])
            if pcd[3].startswith('{'):
                ExtraOption += " --pcd " + pcdname + '=' + 'H' + '"' + pcd[3] + '"'
            else:
                ExtraOption += " --pcd " + pcdname + '=' + pcd[3]

        MakefileName = self.getMakefileName()
        SubBuildCommandList = []
        for A in MyAgo.ArchList:
            Command = self._MAKE_TEMPLATE_[self._Platform] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}
            SubBuildCommandList.append(Command)

        MakefileTemplateDict = {
            "makefile_header"           : self._FILE_HEADER_[self._FileType],
            "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),
            "make_path"                 : MyAgo.ToolDefinition["MAKE"]["PATH"],
            "platform_name"             : MyAgo.Name,
            "platform_guid"             : MyAgo.Guid,
            "platform_version"          : MyAgo.Version,
            "platform_build_directory"  : MyAgo.BuildDir,
            "conf_directory"            : GlobalData.gConfDirectory,

            "toolchain_tag"             : MyAgo.ToolChain,
            "build_target"              : MyAgo.BuildTarget,
            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
            'arch'                      : list(MyAgo.ArchList),
            "build_architecture_list"   : ','.join(MyAgo.ArchList),
            "separator"                 : Separator,
            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
            "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),
            "sub_build_command"         : SubBuildCommandList,
            "fdf_file"                  : FdfFileList,
            "active_platform"           : str(MyAgo),
            "fd"                        : MyAgo.FdTargetList,
            "fv"                        : MyAgo.FvTargetList,
            "cap"                       : MyAgo.CapTargetList,
            "extra_options"             : ExtraOption,
            "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:
            if not ModuleAutoGen.IsBinaryModule:
                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:
            if not LibraryAutoGen.IsBinaryModule:
                DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
        return DirList

## Find dependencies for one source file
#
#  By searching recursively "#include" directive in file, find out all the
#  files needed by given source file. The dependencies 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(AutoGenObject, FileCache, File, ForceList, SearchPathList):
    EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File)
    FileStack = [File] + ForceList
    DependencySet = set()

    if AutoGenObject.Arch not in gDependencyDatabase:
        gDependencyDatabase[AutoGenObject.Arch] = {}
    DepDb = gDependencyDatabase[AutoGenObject.Arch]

    while len(FileStack) > 0:
        F = FileStack.pop()

        FullPathDependList = []
        if F in FileCache:
            for CacheFile in FileCache[F]:
                FullPathDependList.append(CacheFile)
                if CacheFile not in DependencySet:
                    FileStack.append(CacheFile)
            DependencySet.update(FullPathDependList)
            continue

        CurrentFileDependencyList = []
        if F in DepDb:
            CurrentFileDependencyList = DepDb[F]
        else:
            try:
                Fd = open(F.Path, 'rb')
                FileContent = Fd.read()
                Fd.close()
            except BaseException as X:
                EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F.Path + "\n\t" + str(X))
            if len(FileContent) == 0:
                continue
            try:
                if FileContent[0] == 0xff or FileContent[0] == 0xfe:
                    FileContent = FileContent.decode('utf-16')
                else:
                    FileContent = FileContent.decode()
            except:
                # The file is not txt file. for example .mcb file
                continue
            IncludedFileList = gIncludePattern.findall(FileContent)

            for Inc in IncludedFileList:
                Inc = Inc.strip()
                # 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, always build the file by
                        # returning a empty dependency
                        FileCache[File] = []
                        return []
                Inc = os.path.normpath(Inc)
                CurrentFileDependencyList.append(Inc)
            DepDb[F] = CurrentFileDependencyList

        CurrentFilePath = F.Dir
        PathList = [CurrentFilePath] + SearchPathList
        for Inc in CurrentFileDependencyList:
            for SearchPath in PathList:
                FilePath = os.path.join(SearchPath, Inc)
                if FilePath in gIsFileMap:
                    if not gIsFileMap[FilePath]:
                        continue
                # If isfile is called too many times, the performance is slow down.
                elif not os.path.isfile(FilePath):
                    gIsFileMap[FilePath] = False
                    continue
                else:
                    gIsFileMap[FilePath] = True
                FilePath = PathClass(FilePath)
                FullPathDependList.append(FilePath)
                if FilePath not in DependencySet:
                    FileStack.append(FilePath)
                break
            else:
                EdkLogger.debug(EdkLogger.DEBUG_9, "%s included by %s was not found "\
                                "in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList)))

        FileCache[F] = FullPathDependList
        DependencySet.update(FullPathDependList)

    DependencySet.update(ForceList)
    if File in DependencySet:
        DependencySet.remove(File)
    DependencyList = list(DependencySet)  # remove duplicate ones

    return DependencyList

# This acts like the main() function for the script, unless it is 'import'ed into another script.
if __name__ == '__main__':
    pass
