## @file
# Create makefile for MS nmake and GNU make
#
# Copyright (c) 2007 - 2017, 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 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.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 = ${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}

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.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"

        for k, v in self._AutoGenObject.Module.Defines.iteritems():
            if k not in self._AutoGenObject.Macros.keys():
                self._AutoGenObject.Macros[k] = v

        if 'MODULE_ENTRY_POINT' not in self._AutoGenObject.Macros.keys():
            self._AutoGenObject.Macros['MODULE_ENTRY_POINT'] = ModuleEntryPoint
        if 'ARCH_ENTRY_POINT' not in self._AutoGenObject.Macros.keys():
            self._AutoGenObject.Macros['ARCH_ENTRY_POINT'] = ArchEntryPoint
        if 'IMAGE_ENTRY_POINT' not in self._AutoGenObject.Macros.keys():
            self._AutoGenObject.Macros['IMAGE_ENTRY_POINT'] = ImageEntryPoint

        PCI_COMPRESS_Flag = False
        for k, v in self._AutoGenObject.Module.Defines.iteritems():
            if 'PCI_COMPRESS' == k and 'TRUE' == v:
                PCI_COMPRESS_Flag = True

        # 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)
                        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(self._AutoGenObject.OutputDir, 'respfilelist.txt')
        if RespDict:
            RespFileListContent = ''
            for Resp in RespDict.keys():
                RespFile = os.path.join(self._AutoGenObject.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 + os.linesep
                RespFileListContent += NewRespStr + os.linesep
            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 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 = []  # [IncPrefix + r"C:\Users\bfeng1\workspace\pycparser\utils\fake_libc_include"]
        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)

        package_rel_dir = self._AutoGenObject.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,
            "platform_dir"              : self._AutoGenObject.Macros["PLATFORM_DIR"],

            "module_name"               : self._AutoGenObject.Name,
            "module_guid"               : self._AutoGenObject.Guid,
            "module_name_guid"          : self._AutoGenObject._GetUniqueBaseName(),
            "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_dir"                : mws.join (self.Macros["WORKSPACE"], self._AutoGenObject.SourceDir),
            "package_relative_directory": package_rel_dir,
            "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 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.keys():
                                if '$('+ Flag +')' in SingleCommandList[0]:
                                    Tool = Flag
                                    break
                        if Tool:
                            SingleCommandLength += len(self._AutoGenObject._BuildOption[Tool]['PATH'])
                            for item in SingleCommandList[1:]:
                                if FlagDict[Tool]['Macro'] in item:
                                    Str = self._AutoGenObject._BuildOption[Tool]['FLAGS']
                                    for Option in self._AutoGenObject.BuildOption.keys():
                                        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.keys():
                                            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.keys():
                                        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.keys():
                                            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.keys():
                    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.keys():
                            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.keys():
                                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 = []
        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

            self._AutoGenObject.AutoGenDepSet |= set(self.FileDependency[File])

            # 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:
                        # gnu tools need forward slash path separater, 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)

                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 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 = ${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
    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 = mws.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,
            "platform_dir"              : self._AutoGenObject.Macros["PLATFORM_DIR"],

            "module_name"               : self._AutoGenObject.Name,
            "module_guid"               : self._AutoGenObject.Guid,
            "module_name_guid"          : self._AutoGenObject._GetUniqueBaseName(),
            "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,
            "module_dir"                : mws.join (self._AutoGenObject.WorkspaceDir, 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 = ${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
    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)
        self.LibraryMakeCommandList = LibraryMakeCommandList

        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,
            "platform_dir"              : self._AutoGenObject.Macros["PLATFORM_DIR"],

            "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:
            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

    _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('''${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
    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"

        if GlobalData.gIgnoreSource:
            ExtraOption += " --ignore-sources"

        if GlobalData.BuildOptionPcd:
            for index, option in enumerate(GlobalData.gCommand):
                if "--pcd" == option and GlobalData.gCommand[index+1]:
                    pcdName, pcdValue = GlobalData.gCommand[index+1].split('=')
                    if pcdValue.startswith('H'):
                        pcdValue = 'H' + '"' + pcdValue[1:] + '"'
                        ExtraOption += " --pcd " + pcdName + '=' + pcdValue
                    elif pcdValue.startswith('L'):
                        pcdValue = 'L' + '"' + pcdValue[1:] + '"'
                        ExtraOption += " --pcd " + pcdName + '=' + pcdValue
                    else:
                        ExtraOption += " --pcd " + GlobalData.gCommand[index+1]

        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,
            "conf_directory"            : GlobalData.gConfDirectory,

            "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:
            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

    _TemplateDict = property(_CreateTemplateDict)

# This acts like the main() function for the script, unless it is 'import'ed into another script.
if __name__ == '__main__':
    pass

