## @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
#
    '''

    ## Fixed header string for makefile
    _GMAKE_MAKEFILE_HEADER = '''
ifeq (Windows, $(findstring Windows,$(OS)))
  SHELL := cmd.exe
endif
    '''


    ## Header string for each type of build file
    _FILE_HEADER_ = {
        NMAKE_FILETYPE :   _MAKEFILE_HEADER % _FILE_NAME_[NMAKE_FILETYPE],
        GMAKE_FILETYPE :   (_MAKEFILE_HEADER + _GMAKE_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.BuildTargetList = []           # [target string]
        self.CommonFileDependency = []
        self.FileListMacros = {}
        self.ListFileMacros = {}
        self.ObjTargetDict = OrderedDict()
        self.FileCache = {}
        self.LibraryMakefileList = []
        self.LibraryBuildDirectoryList = []
        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))

## 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.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
