## @file
# Create makefile for MS nmake and GNU make
#
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution.  The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#

## Import Modules
#
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,
}

## default makefile type
gMakeType = ""
if sys.platform == "win32":
    gMakeType = "nmake"
else:
    gMakeType = "gmake"


## BuildFile class
#
#  This base class encapsules build file and its generation. It uses template to generate
#  the content of build file. The content of build file will be got from AutoGen objects.
#
class BuildFile(object):
    ## template used to generate the build file (i.e. makefile if using make)
    _TEMPLATE_ = TemplateString('')

    _DEFAULT_FILE_NAME_ = "Makefile"

    ## default file name for each type of build file
    _FILE_NAME_ = {
        "nmake" :   "Makefile",
        "gmake" :   "GNUmakefile"
    }

    ## Fixed header string for makefile
    _MAKEFILE_HEADER = '''#
# DO NOT EDIT
# This file is auto-generated by build utility
#
# Module Name:
#
#   %s
#
# Abstract:
#
#   Auto-generated makefile for building modules, libraries or platform
#
    '''

    ## Header string for each type of build file
    _FILE_HEADER_ = {
        "nmake" :   _MAKEFILE_HEADER % _FILE_NAME_["nmake"],
        "gmake" :   _MAKEFILE_HEADER % _FILE_NAME_["gmake"]
    }

    ## shell commands which can be used in build file in the form of macro
    #   $(CP)     copy file command
    #   $(MV)     move file command
    #   $(RM)     remove file command
    #   $(MD)     create dir command
    #   $(RD)     remove dir command
    #
    _SHELL_CMD_ = {
        "nmake" : {
            "CP"    :   "copy /y",
            "MV"    :   "move /y",
            "RM"    :   "del /f /q",
            "MD"    :   "mkdir",
            "RD"    :   "rmdir /s /q",
        },

        "gmake" : {
            "CP"    :   "cp -f",
            "MV"    :   "mv -f",
            "RM"    :   "rm -f",
            "MD"    :   "mkdir -p",
            "RD"    :   "rm -r -f",
        }
    }

    ## directory separator
    _SEP_ = {
        "nmake" :   "\\",
        "gmake" :   "/"
    }

    ## directory creation template
    _MD_TEMPLATE_ = {
        "nmake" :   'if not exist %(dir)s $(MD) %(dir)s',
        "gmake" :   "$(MD) %(dir)s"
    }

    ## directory removal template
    _RD_TEMPLATE_ = {
        "nmake" :   'if exist %(dir)s $(RD) %(dir)s',
        "gmake" :   "$(RD) %(dir)s"
    }
    ## cp if exist
    _CP_TEMPLATE_ = {
        "nmake" :   'if exist %(Src)s $(CP) %(Src)s %(Dst)s',
        "gmake" :   "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"
    }

    _CD_TEMPLATE_ = {
        "nmake" :   'if exist %(dir)s cd %(dir)s',
        "gmake" :   "test -e %(dir)s && cd %(dir)s"
    }

    _MAKE_TEMPLATE_ = {
        "nmake" :   'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s',
        "gmake" :   'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s'
    }

    _INCLUDE_CMD_ = {
        "nmake" :   '!INCLUDE',
        "gmake" :   "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
        self._FileType = gMakeType

    ## Create build file
    #
    #   @param  FileType    Type of build file. Only nmake and gmake are supported now.
    #
    #   @retval TRUE        The build file is created or re-created successfully
    #   @retval FALSE       The build file exists and is the same as the one to be generated
    #
    def Generate(self, FileType=gMakeType):
        if FileType not in self._FILE_NAME_:
            EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType,
                            ExtraData="[%s]" % str(self._AutoGenObject))
        self._FileType = FileType
        FileContent = self._TEMPLATE_.Replace(self._TemplateDict)
        FileName = self._FILE_NAME_[FileType]
        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._FileType] % {'dir':Dir} for Dir in DirList]

    ## Return a list of directory removal command string
    #
    #   @param      DirList     The list of directory to be removed
    #
    #   @retval     list        The directory removal command list
    #
    def GetRemoveDirectoryCommand(self, DirList):
        return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]

    def PlaceMacro(self, Path, MacroDefinitions={}):
        if Path.startswith("$("):
            return Path
        else:
            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}

COMMON_DEPS = ${BEGIN}${common_dependency_file} \\
              ${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)

#
# 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.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 = []

    # Compose a dict object containing information used to do replacement in template
    @property
    def _TemplateDict(self):
        if self._FileType not in self._SEP_:
            EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,
                            ExtraData="[%s]" % str(self._AutoGenObject))
        MyAgo = self._AutoGenObject
        Separator = self._SEP_[self._FileType]

        # 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:
                        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
        for File in self.FileCache.keys():
            if not str(File).endswith('.nasm'):
                continue
            IncludePathList = []
            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
                # To specify a literal backslash at the end of the line, precede it with a caret (^)
                if P == MyAgo.IncludePathList[-1] and os.sep == '\\':
                    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}))
            break

        # 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
                )

        BcTargetList = []

        MakefileName = self._FILE_NAME_[self._FileType]
        LibraryMakeCommandList = []
        for D in self.LibraryBuildDirectoryList:
            Command = self._MAKE_TEMPLATE_[self._FileType] % {"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._FileType].keys()),
            "shell_command"             : list(self._SHELL_CMD_[self._FileType].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,
        }

        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 :" %(Dst))
                        self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._FileType] %{'Src': Src, 'Dst': Dst})

            FfsCmdList = Cmd[0]
            for index, Str in enumerate(FfsCmdList):
                if '-o' == Str:
                    OutputFile = FfsCmdList[index + 1]
                if '-i' == 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 = self.GetFileDependency(
                                    SourceFileList,
                                    ForceIncludedFile,
                                    self._AutoGenObject.IncludePathList + self._AutoGenObject.BuildOptionIncPathList
                                    )
        DepSet = None
        for File,Dependency in FileDependencyDict.items():
            if not Dependency:
                FileDependencyDict[File] = ['$(FORCE_REBUILD)']
                continue

            self._AutoGenObject.AutoGenDepSet |= set(Dependency)

            # skip non-C files
            if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":
                continue
            elif DepSet is None:
                DepSet = set(Dependency)
            else:
                DepSet &= set(Dependency)
        # in case nothing in SourceFileList
        if DepSet is None:
            DepSet = set()
        #
        # Extract common files list in the dependency files
        #
        for File in DepSet:
            self.CommonFileDependency.append(self.PlaceMacro(File.Path, self.Macros))

        for File in FileDependencyDict:
            # skip non-C files
            if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":
                continue
            NewDepSet = set(FileDependencyDict[File])
            NewDepSet -= DepSet
            FileDependencyDict[File] = ["$(COMMON_DEPS)"] + list(NewDepSet)

        # Convert target description object to target string in makefile
        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 = []
                # Add force-dependencies
                for Dep in T.Dependencies:
                    Deps.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)

                # 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)

                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))

    ## 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] = self.GetDependencyList(F, ForceInculeList, SearchPathList)
        return Dependency

    ## Find dependencies for one source file
    #
    #  By searching recursively "#include" directive in file, find out all the
    #  files needed by given source file. The 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(self, File, ForceList, SearchPathList):
        EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File)
        FileStack = [File] + ForceList
        DependencySet = set()

        if self._AutoGenObject.Arch not in gDependencyDatabase:
            gDependencyDatabase[self._AutoGenObject.Arch] = {}
        DepDb = gDependencyDatabase[self._AutoGenObject.Arch]

        while len(FileStack) > 0:
            F = FileStack.pop()

            FullPathDependList = []
            if F in self.FileCache:
                for CacheFile in self.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
                            self.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)))

            self.FileCache[F] = FullPathDependList
            DependencySet.update(FullPathDependList)

        DependencySet.update(ForceList)
        if File in DependencySet:
            DependencySet.remove(File)
        DependencyList = list(DependencySet)  # remove duplicate ones

        return DependencyList

## 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)"]

    # Compose a dict object containing information used to do replacement in template
    @property
    def _TemplateDict(self):
        Separator = self._SEP_[self._FileType]
        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._FILE_NAME_[self._FileType]
        MakefileTemplateDict = {
            "makefile_header"           : self._FILE_HEADER_[self._FileType],
            "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
            "platform_name"             : self.PlatformInfo.Name,
            "platform_guid"             : self.PlatformInfo.Guid,
            "platform_version"          : self.PlatformInfo.Version,
            "platform_relative_directory": self.PlatformInfo.SourceDir,
            "platform_output_directory" : self.PlatformInfo.OutputDir,
            "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._FileType].keys()),
            "shell_command"             : list(self._SHELL_CMD_[self._FileType].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 = []

    # Compose a dict object containing information used to do replacement in template
    @property
    def _TemplateDict(self):
        Separator = self._SEP_[self._FileType]

        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._FILE_NAME_[self._FileType]
        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._FileType] % {"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._FileType] % {"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._FileType].keys()),
            "shell_command"             : list(self._SHELL_CMD_[self._FileType].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 = []

    # Compose a dict object containing information used to do replacement in template
    @property
    def _TemplateDict(self):
        Separator = self._SEP_[self._FileType]

        # 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 GlobalData.gEnableGenfdsMultiThread:
            ExtraOption += " --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._FILE_NAME_[self._FileType]
        SubBuildCommandList = []
        for A in MyAgo.ArchList:
            Command = self._MAKE_TEMPLATE_[self._FileType] % {"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._FileType].keys()),
            "shell_command"             : list(self._SHELL_CMD_[self._FileType].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

# This acts like the main() function for the script, unless it is 'import'ed into another script.
if __name__ == '__main__':
    pass

