## @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 = []
        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

