## @file
# Create makefile for MS nmake and GNU make
#
# Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2020, 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.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 -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", "RVCT" : "-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:
            self._FileType = ""
        elif "nmake" in MakePath:
            self._FileType = NMAKE_FILETYPE
        else:
            self._FileType = "gmake"

        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 MyAgo.BuildOption:
            for Attr in MyAgo.BuildOption[Tool]:
                Value = MyAgo.BuildOption[Tool][Attr]
                if Attr == "FAMILY":
                    continue
                elif Attr == "PATH":
                    ToolsDef.append("%s = %s" % (Tool, Value))
                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))
            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()
        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 self._AutoGenObject.Macros[Macro] in str:
                str = str.replace(self._AutoGenObject.Macros[Macro], '$(' + 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':
                            RespDict[Key] = Value.replace('\\', '/')
                        else:
                            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):
        #
        # 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:
            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)
                    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))

    def ParserCCodeFile(self, T, Type, CmdSumDict, CmdTargetDict, CmdCppDict, DependencyDict):
        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()):
                        CmdTargetDict[CmdSign] = Item.replace(Temp, CmdSign)
                    else:
                        CmdTargetDict[CmdSign] = "%s %s" % (CmdTargetDict[CmdSign], SingleCommandList[-1])
                    Index = CommandList.index(Item)
                    CommandList.pop(Index)
                    if SingleCommandList[-1].endswith("%s%s.c" % (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))
                        T.Commands[Index] = '%s\n\t%s' % (' \\\n\t'.join(Cpplist), 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
