## @file
# Create makefile for MS nmake and GNU make
#
# Copyright (c) 2007 - 2010, 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
#
import os
import sys
import string
import re
import os.path as path

from Common.BuildToolError import *
from Common.Misc import *
from Common.String import *
from BuildEngine import *
import Common.GlobalData as GlobalData

## 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"
    }

    _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_ = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I", "RVCT" : "-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 <= 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 = $(WORKSPACE)${separator}${platform_relative_directory}
PLATFORM_OUTPUT_DIR = ${platform_output_directory}

#
# Module Macro Definition
#
MODULE_NAME = ${module_name}
MODULE_GUID = ${module_guid}
MODULE_VERSION = ${module_version}
MODULE_TYPE = ${module_type}
MODULE_FILE = ${module_file}
MODULE_FILE_BASE_NAME = ${module_file_base_name}
BASE_NAME = $(MODULE_NAME)
MODULE_RELATIVE_DIR = ${module_relative_directory}
MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}

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}

#
# clean all generated files
#
cleanall:
${BEGIN}\t${cleanall_command}
${END}\t$(RM) *.pdb *.idb > NUL 2>&1
\t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi

#
# clean 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.SourceFileDatabase = {}        # {file type : file path}
        self.DestFileDatabase = {}          # {file type : file path}
        self.FileBuildTargetList = []       # [(src, target string)]
        self.BuildTargetList = []           # [target string]
        self.PendingBuildTargetList = []    # [FileBuildRule objects]
        self.CommonFileDependency = []
        self.FileListMacros = {}
        self.ListFileMacros = {}

        self.FileCache = {}
        self.FileDependency = []
        self.LibraryBuildCommandList = []
        self.LibraryFileList = []
        self.LibraryMakefileList = []
        self.LibraryBuildDirectoryList = []
        self.SystemLibraryList = []
        self.Macros = sdict()
        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"]

    # Compose a dict object containing information used to do replacement in template
    def _CreateTemplateDict(self):
        if self._FileType not in self._SEP_:
            EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,
                            ExtraData="[%s]" % str(self._AutoGenObject))
        Separator = self._SEP_[self._FileType]

        # break build if no source files and binary files are found
        if len(self._AutoGenObject.SourceFileList) == 0 and len(self._AutoGenObject.BinaryFileList) == 0:
            EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"
                            % (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch),
                            ExtraData="[%s]" % str(self._AutoGenObject))

        # convert dependent libraries to build command
        self.ProcessDependentLibrary()
        if len(self._AutoGenObject.Module.ModuleEntryPointList) > 0:
            ModuleEntryPoint = self._AutoGenObject.Module.ModuleEntryPointList[0]
        else:
            ModuleEntryPoint = "_ModuleEntryPoint"

        # Intel EBC compiler enforces EfiMain
        if self._AutoGenObject.AutoGenVersion < 0x00010005 and self._AutoGenObject.Arch == "EBC":
            ArchEntryPoint = "EfiMain"
        else:
            ArchEntryPoint = ModuleEntryPoint

        if self._AutoGenObject.Arch == "EBC":
            # EBC compiler always use "EfiStart" as entry point. Only applies to EdkII modules
            ImageEntryPoint = "EfiStart"
        elif self._AutoGenObject.AutoGenVersion < 0x00010005:
            # Edk modules use entry point specified in INF file
            ImageEntryPoint = ModuleEntryPoint
        else:
            # EdkII modules always use "_ModuleEntryPoint" as entry point
            ImageEntryPoint = "_ModuleEntryPoint"

        # tools definitions
        ToolsDef = []
        IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]
        for Tool in self._AutoGenObject.BuildOption:
            for Attr in self._AutoGenObject.BuildOption[Tool]:
                Value = self._AutoGenObject.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, self._AutoGenObject.IncludePathList)
                    ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value))
            ToolsDef.append("")

        # convert source files and binary files to build targets
        self.ResultFileList = [str(T.Target) for T in self._AutoGenObject.CodaTargetList]
        if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:        
            EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",
                            ExtraData="[%s]" % str(self._AutoGenObject))

        self.ProcessBuildTargetList()

        # 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  self._AutoGenObject.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)

        # Generate macros used to represent files containing list of input files
        for ListFileMacro in self.ListFileMacros:
            ListFileName = os.path.join(self._AutoGenObject.OutputDir, "%s.lst" % ListFileMacro.lower()[:len(ListFileMacro)-5])
            FileMacroList.append("%s = %s" % (ListFileMacro, ListFileName))
            SaveFileOnChange(
                ListFileName,
                "\n".join(self.ListFileMacros[ListFileMacro]),
                False
                )

        # Edk modules need <BaseName>StrDefs.h for string ID
        #if self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.UnicodeFileList) > 0:
        #    BcTargetList = ['strdefs']
        #else:
        #    BcTargetList = []
        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)

        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,

            "module_name"               : self._AutoGenObject.Name,
            "module_guid"               : self._AutoGenObject.Guid,
            "module_version"            : self._AutoGenObject.Version,
            "module_type"               : self._AutoGenObject.ModuleType,
            "module_file"               : self._AutoGenObject.MetaFile.Name,
            "module_file_base_name"     : self._AutoGenObject.MetaFile.BaseName,
            "module_relative_directory" : self._AutoGenObject.SourceDir,
            "module_extra_defines"      : ["%s = %s" % (k, v) for k,v in self._AutoGenObject.Module.Defines.iteritems()],

            "architecture"              : self._AutoGenObject.Arch,
            "toolchain_tag"             : self._AutoGenObject.ToolChain,
            "build_target"              : self._AutoGenObject.BuildTarget,

            "platform_build_directory"  : self.PlatformInfo.BuildDir,
            "module_build_directory"    : self._AutoGenObject.BuildDir,
            "module_output_directory"   : self._AutoGenObject.OutputDir,
            "module_debug_directory"    : self._AutoGenObject.DebugDir,

            "separator"                 : Separator,
            "module_tool_definitions"   : ToolsDef,

            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),
            "shell_command"             : 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 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 = []
        for Target in self._AutoGenObject.IntroTargetList:
            SourceFileList.extend(Target.Inputs)

        self.FileDependency = self.GetFileDependency(
                                    SourceFileList,
                                    ForceIncludedFile,
                                    self._AutoGenObject.IncludePathList + self._AutoGenObject.BuildOptionIncPathList
                                    )
        DepSet = None
        for File in self.FileDependency:
            if not self.FileDependency[File]:
                self.FileDependency[File] = ['$(FORCE_REBUILD)']
                continue
            # skip non-C files
            if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":
                continue
            elif DepSet == None:
                DepSet = set(self.FileDependency[File])
            else:
                DepSet &= set(self.FileDependency[File])
        # in case nothing in SourceFileList
        if DepSet == None:
            DepSet = set()
        #
        # Extract common files list in the dependency files
        #
        for File in DepSet:
            self.CommonFileDependency.append(self.PlaceMacro(File.Path, self.Macros))

        for File in self.FileDependency:
            # skip non-C files
            if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":
                continue
            NewDepSet = set(self.FileDependency[File])
            NewDepSet -= DepSet
            self.FileDependency[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 self.FileDependency:
                    for F in self.FileDependency[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:
                        self.ListFileMacros[T.ListFileMacro].append(str(F))
                        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)

                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:
            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 dependecies will be only searched
    #  in given search path list.
    #
    #   @param      File            The source file
    #   @param      ForceInculeList The list of files which will be included forcely
    #   @param      SearchPathList  The list of search path
    #
    #   @retval     list            The list of files the given source file depends on
    #
    def GetDependencyList(self, File, ForceList, SearchPathList):
        EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File)
        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, 'r')
                except BaseException, X:
                    EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F.Path+"\n\t"+str(X))

                FileContent = Fd.read()
                Fd.close()
                if len(FileContent) == 0:
                    continue

                if FileContent[0] == 0xff or FileContent[0] == 0xfe:
                    FileContent = unicode(FileContent, "utf-16")
                IncludedFileList = gIncludePattern.findall(FileContent)

                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

    _TemplateDict = property(_CreateTemplateDict)

## CustomMakefile class
#
#  This class encapsules makefie and its generation for module. It uses template to generate
#  the content of makefile. The content of makefile will be got from ModuleAutoGen object.
#
class CustomMakefile(BuildFile):
    ## template used to generate the makefile for module with custom makefile
    _TEMPLATE_ = 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 = $(WORKSPACE)${separator}${platform_relative_directory}
PLATFORM_OUTPUT_DIR = ${platform_output_directory}

#
# Module Macro Definition
#
MODULE_NAME = ${module_name}
MODULE_GUID = ${module_guid}
MODULE_VERSION = ${module_version}
MODULE_TYPE = ${module_type}
MODULE_FILE = ${module_file}
MODULE_FILE_BASE_NAME = ${module_file_base_name}
BASE_NAME = $(MODULE_NAME)
MODULE_RELATIVE_DIR = ${module_relative_directory}
MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}

#
# Build Configuration Macro Definition
#
ARCH = ${architecture}
TOOLCHAIN = ${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
    def _CreateTemplateDict(self):
        Separator = self._SEP_[self._FileType]
        if self._FileType not in self._AutoGenObject.CustomMakefile:
            EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,
                            ExtraData="[%s]" % str(self._AutoGenObject))
        MakefilePath = os.path.join(
                                self._AutoGenObject.WorkspaceDir,
                                self._AutoGenObject.CustomMakefile[self._FileType]
                                )
        try:
            CustomMakefile = open(MakefilePath, 'r').read()
        except:
            EdkLogger.error('build', FILE_OPEN_FAILURE, File=str(self._AutoGenObject),
                            ExtraData=self._AutoGenObject.CustomMakefile[self._FileType])

        # tools definitions
        ToolsDef = []
        for Tool in self._AutoGenObject.BuildOption:
            # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.
            if Tool == "MAKE":
                continue
            for Attr in self._AutoGenObject.BuildOption[Tool]:
                if Attr == "FAMILY":
                    continue
                elif Attr == "PATH":
                    ToolsDef.append("%s = %s" % (Tool, self._AutoGenObject.BuildOption[Tool][Attr]))
                else:
                    ToolsDef.append("%s_%s = %s" % (Tool, Attr, self._AutoGenObject.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,

            "module_name"               : self._AutoGenObject.Name,
            "module_guid"               : self._AutoGenObject.Guid,
            "module_version"            : self._AutoGenObject.Version,
            "module_type"               : self._AutoGenObject.ModuleType,
            "module_file"               : self._AutoGenObject.MetaFile,
            "module_file_base_name"     : self._AutoGenObject.MetaFile.BaseName,
            "module_relative_directory" : self._AutoGenObject.SourceDir,

            "architecture"              : self._AutoGenObject.Arch,
            "toolchain_tag"             : self._AutoGenObject.ToolChain,
            "build_target"              : self._AutoGenObject.BuildTarget,

            "platform_build_directory"  : self.PlatformInfo.BuildDir,
            "module_build_directory"    : self._AutoGenObject.BuildDir,
            "module_output_directory"   : self._AutoGenObject.OutputDir,
            "module_debug_directory"    : self._AutoGenObject.DebugDir,

            "separator"                 : Separator,
            "module_tool_definitions"   : ToolsDef,

            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),
            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),

            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
            "custom_makefile_content"   : CustomMakefile
        }

        return MakefileTemplateDict

    _TemplateDict = property(_CreateTemplateDict)

## PlatformMakefile class
#
#  This class encapsules makefie and its generation for platform. It uses
# template to generate the content of makefile. The content of makefile will be
# got from PlatformAutoGen object.
#
class PlatformMakefile(BuildFile):
    ## template used to generate the makefile for platform
    _TEMPLATE_ = TemplateString('''\
${makefile_header}

#
# Platform Macro Definition
#
PLATFORM_NAME = ${platform_name}
PLATFORM_GUID = ${platform_guid}
PLATFORM_VERSION = ${platform_version}
PLATFORM_FILE = ${platform_file}
PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}
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 = []

    # Compose a dict object containing information used to do replacement in template
    def _CreateTemplateDict(self):
        Separator = self._SEP_[self._FileType]

        PlatformInfo = self._AutoGenObject
        if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]:
            EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",
                            ExtraData="[%s]" % str(self._AutoGenObject))

        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":PlatformInfo.BuildDir})
            Makefile = os.path.join(D, MakefileName)
            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
            LibraryMakefileList.append(Makefile)
            LibraryMakeCommandList.append(Command)

        ModuleMakefileList = []
        ModuleMakeCommandList = []
        for D in self.ModuleBuildDirectoryList:
            D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.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"                 : PlatformInfo.ToolDefinition["MAKE"]["PATH"],
            "makefile_name"             : MakefileName,
            "platform_name"             : PlatformInfo.Name,
            "platform_guid"             : PlatformInfo.Guid,
            "platform_version"          : PlatformInfo.Version,
            "platform_file"             : self._AutoGenObject.MetaFile,
            "platform_relative_directory": PlatformInfo.SourceDir,
            "platform_output_directory" : PlatformInfo.OutputDir,
            "platform_build_directory"  : PlatformInfo.BuildDir,

            "toolchain_tag"             : PlatformInfo.ToolChain,
            "build_target"              : PlatformInfo.BuildTarget,
            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),
            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),
            "build_architecture_list"   : self._AutoGenObject.Arch,
            "architecture"              : self._AutoGenObject.Arch,
            "separator"                 : Separator,
            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
            "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),
            "library_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:
            DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
        return DirList

    ## Get the root directory list for intermediate files of all libraries build
    #
    #   @retval     list    The list of directory
    #
    def GetLibraryBuildDirectoryList(self):
        DirList = []
        for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
            DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
        return DirList

    _TemplateDict = property(_CreateTemplateDict)

## TopLevelMakefile class
#
#  This class encapsules makefie and its generation for entrance makefile. It
# uses template to generate the content of makefile. The content of makefile
# will be got from WorkspaceAutoGen object.
#
class TopLevelMakefile(BuildFile):
    ## template used to generate toplevel makefile
    _TEMPLATE_ = TemplateString('''\
${makefile_header}

#
# Platform Macro Definition
#
PLATFORM_NAME = ${platform_name}
PLATFORM_GUID = ${platform_guid}
PLATFORM_VERSION = ${platform_version}

#
# 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: modules fds

#
# Initialization target: print build information and create necessary directories
#
init:
\t-@
\t${BEGIN}-@${create_directory_command}
\t${END}
#
# library build target
#
libraries: init
${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) libraries
${END}\t@cd $(BUILD_DIR)

#
# module build target
#
modules: init
${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) modules
${END}\t@cd $(BUILD_DIR)

#
# Flash Device Image Target
#
fds: init
\t-@cd $(FV_DIR)
${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN) -b $(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}

#
# run command for emulator platform only
#
run:
\tcd $(BUILD_DIR)${separator}IA32 && ".${separator}SecMain"
\tcd $(BUILD_DIR)

#
# Clean intermediate files
#
clean:
${BEGIN}\t-@${sub_build_command} clean
${END}\t@cd $(BUILD_DIR)

#
# Clean all generated files except to makefile
#
cleanall:
${BEGIN}\t${cleanall_command}
${END}

#
# Clean all library files
#
cleanlib:
${BEGIN}\t-@${sub_build_command} cleanlib
${END}\t@cd $(BUILD_DIR)\n
''')

    ## Constructor of TopLevelMakefile
    #
    #   @param  Workspace   Object of WorkspaceAutoGen class
    #
    def __init__(self, Workspace):
        BuildFile.__init__(self, Workspace)
        self.IntermediateDirectoryList = []

    # Compose a dict object containing information used to do replacement in template
    def _CreateTemplateDict(self):
        Separator = self._SEP_[self._FileType]

        # any platform autogen object is ok because we just need common information
        PlatformInfo = self._AutoGenObject

        if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]:
            EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",
                            ExtraData="[%s]" % str(self._AutoGenObject))

        for Arch in PlatformInfo.ArchList:
            self.IntermediateDirectoryList.append(Separator.join(["$(BUILD_DIR)", Arch]))
        self.IntermediateDirectoryList.append("$(FV_DIR)")

        # TRICK: for not generating GenFds call in makefile if no FDF file
        MacroList = []
        if PlatformInfo.FdfFile != None and PlatformInfo.FdfFile != "":
            FdfFileList = [PlatformInfo.FdfFile]
            # macros passed to GenFds
            MacroList.append('"%s=%s"' % ("EFI_SOURCE", GlobalData.gEfiSource.replace('\\', '\\\\')))
            MacroList.append('"%s=%s"' % ("EDK_SOURCE", GlobalData.gEdkSource.replace('\\', '\\\\')))
            MacroDict = {}
            MacroDict.update(GlobalData.gGlobalDefines)
            MacroDict.update(GlobalData.gCommandLineDefines)
            MacroDict.pop("EFI_SOURCE", "dummy")
            MacroDict.pop("EDK_SOURCE", "dummy")
            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"

        MakefileName = self._FILE_NAME_[self._FileType]
        SubBuildCommandList = []
        for A in PlatformInfo.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"                 : PlatformInfo.ToolDefinition["MAKE"]["PATH"],
            "platform_name"             : PlatformInfo.Name,
            "platform_guid"             : PlatformInfo.Guid,
            "platform_version"          : PlatformInfo.Version,
            "platform_build_directory"  : PlatformInfo.BuildDir,

            "toolchain_tag"             : PlatformInfo.ToolChain,
            "build_target"              : PlatformInfo.BuildTarget,
            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),
            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),
            'arch'                      : list(PlatformInfo.ArchList),
            "build_architecture_list"   : ','.join(PlatformInfo.ArchList),
            "separator"                 : Separator,
            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
            "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),
            "sub_build_command"         : SubBuildCommandList,
            "fdf_file"                  : FdfFileList,
            "active_platform"           : str(PlatformInfo),
            "fd"                        : PlatformInfo.FdTargetList,
            "fv"                        : PlatformInfo.FvTargetList,
            "cap"                       : PlatformInfo.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:
            DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
        return DirList

    ## Get the root directory list for intermediate files of all libraries build
    #
    #   @retval     list    The list of directory
    #
    def GetLibraryBuildDirectoryList(self):
        DirList = []
        for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
            DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
        return DirList

    _TemplateDict = property(_CreateTemplateDict)

# This acts like the main() function for the script, unless it is 'import'ed into another script.
if __name__ == '__main__':
    pass

