## @file
# Create makefile for MS nmake and GNU make
#
# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
from __future__ import absolute_import
from AutoGen.AutoGen import AutoGen
from Common.LongFilePathSupport import LongFilePath, CopyLongFilePath
from Common.BuildToolError import *
from Common.DataType import *
from Common.Misc import *
from Common.StringUtils import NormPath,GetSplitList
from collections import defaultdict
from Workspace.WorkspaceCommon import OrderedListDict
import os.path as path
import copy
import hashlib
from . import InfSectionParser
from . import GenC
from . import GenMake
from . import GenDepex
from io import BytesIO
from GenPatchPcdTable.GenPatchPcdTable import parsePcdInfoFromMapFile
from Workspace.MetaFileCommentParser import UsageList
from .GenPcdDb import CreatePcdDatabaseCode
from Common.caching import cached_class_function
from AutoGen.ModuleAutoGenHelper import PlatformInfo,WorkSpaceInfo
import json
import tempfile

## Mapping Makefile type
gMakeTypeMap = {TAB_COMPILER_MSFT:"nmake", "GCC":"gmake"}
#
# Regular expression for finding Include Directories, the difference between MSFT and INTEL/GCC/RVCT
# is the former use /I , the Latter used -I to specify include directories
#
gBuildOptIncludePatternMsft = re.compile(r"(?:.*?)/I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)
gBuildOptIncludePatternOther = re.compile(r"(?:.*?)-I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)

## default file name for AutoGen
gAutoGenCodeFileName = "AutoGen.c"
gAutoGenHeaderFileName = "AutoGen.h"
gAutoGenStringFileName = "%(module_name)sStrDefs.h"
gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk"
gAutoGenDepexFileName = "%(module_name)s.depex"
gAutoGenImageDefFileName = "%(module_name)sImgDefs.h"
gAutoGenIdfFileName = "%(module_name)sIdf.hpk"
gInfSpecVersion = "0x00010017"

#
# Match name = variable
#
gEfiVarStoreNamePattern = re.compile("\s*name\s*=\s*(\w+)")
#
# The format of guid in efivarstore statement likes following and must be correct:
# guid = {0xA04A27f4, 0xDF00, 0x4D42, {0xB5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3D}}
#
gEfiVarStoreGuidPattern = re.compile("\s*guid\s*=\s*({.*?{.*?}\s*})")

#
# Template string to generic AsBuilt INF
#
gAsBuiltInfHeaderString = TemplateString("""${header_comments}

# DO NOT EDIT
# FILE auto-generated

[Defines]
  INF_VERSION                = ${module_inf_version}
  BASE_NAME                  = ${module_name}
  FILE_GUID                  = ${module_guid}
  MODULE_TYPE                = ${module_module_type}${BEGIN}
  VERSION_STRING             = ${module_version_string}${END}${BEGIN}
  PCD_IS_DRIVER              = ${pcd_is_driver_string}${END}${BEGIN}
  UEFI_SPECIFICATION_VERSION = ${module_uefi_specification_version}${END}${BEGIN}
  PI_SPECIFICATION_VERSION   = ${module_pi_specification_version}${END}${BEGIN}
  ENTRY_POINT                = ${module_entry_point}${END}${BEGIN}
  UNLOAD_IMAGE               = ${module_unload_image}${END}${BEGIN}
  CONSTRUCTOR                = ${module_constructor}${END}${BEGIN}
  DESTRUCTOR                 = ${module_destructor}${END}${BEGIN}
  SHADOW                     = ${module_shadow}${END}${BEGIN}
  PCI_VENDOR_ID              = ${module_pci_vendor_id}${END}${BEGIN}
  PCI_DEVICE_ID              = ${module_pci_device_id}${END}${BEGIN}
  PCI_CLASS_CODE             = ${module_pci_class_code}${END}${BEGIN}
  PCI_REVISION               = ${module_pci_revision}${END}${BEGIN}
  BUILD_NUMBER               = ${module_build_number}${END}${BEGIN}
  SPEC                       = ${module_spec}${END}${BEGIN}
  UEFI_HII_RESOURCE_SECTION  = ${module_uefi_hii_resource_section}${END}${BEGIN}
  MODULE_UNI_FILE            = ${module_uni_file}${END}

[Packages.${module_arch}]${BEGIN}
  ${package_item}${END}

[Binaries.${module_arch}]${BEGIN}
  ${binary_item}${END}

[PatchPcd.${module_arch}]${BEGIN}
  ${patchablepcd_item}
${END}

[Protocols.${module_arch}]${BEGIN}
  ${protocol_item}
${END}

[Ppis.${module_arch}]${BEGIN}
  ${ppi_item}
${END}

[Guids.${module_arch}]${BEGIN}
  ${guid_item}
${END}

[PcdEx.${module_arch}]${BEGIN}
  ${pcd_item}
${END}

[LibraryClasses.${module_arch}]
## @LIB_INSTANCES${BEGIN}
#  ${libraryclasses_item}${END}

${depexsection_item}

${userextension_tianocore_item}

${tail_comments}

[BuildOptions.${module_arch}]
## @AsBuilt${BEGIN}
##   ${flags_item}${END}
""")
#
# extend lists contained in a dictionary with lists stored in another dictionary
# if CopyToDict is not derived from DefaultDict(list) then this may raise exception
#
def ExtendCopyDictionaryLists(CopyToDict, CopyFromDict):
    for Key in CopyFromDict:
        CopyToDict[Key].extend(CopyFromDict[Key])

# Create a directory specified by a set of path elements and return the full path
def _MakeDir(PathList):
    RetVal = path.join(*PathList)
    CreateDirectory(RetVal)
    return RetVal

#
# Convert string to C format array
#
def _ConvertStringToByteArray(Value):
    Value = Value.strip()
    if not Value:
        return None
    if Value[0] == '{':
        if not Value.endswith('}'):
            return None
        Value = Value.replace(' ', '').replace('{', '').replace('}', '')
        ValFields = Value.split(',')
        try:
            for Index in range(len(ValFields)):
                ValFields[Index] = str(int(ValFields[Index], 0))
        except ValueError:
            return None
        Value = '{' + ','.join(ValFields) + '}'
        return Value

    Unicode = False
    if Value.startswith('L"'):
        if not Value.endswith('"'):
            return None
        Value = Value[1:]
        Unicode = True
    elif not Value.startswith('"') or not Value.endswith('"'):
        return None

    Value = eval(Value)         # translate escape character
    NewValue = '{'
    for Index in range(0, len(Value)):
        if Unicode:
            NewValue = NewValue + str(ord(Value[Index]) % 0x10000) + ','
        else:
            NewValue = NewValue + str(ord(Value[Index]) % 0x100) + ','
    Value = NewValue + '0}'
    return Value

## ModuleAutoGen class
#
# This class encapsules the AutoGen behaviors for the build tools. In addition to
# the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according
# to the [depex] section in module's inf file.
#
class ModuleAutoGen(AutoGen):
    # call super().__init__ then call the worker function with different parameter count
    def __init__(self, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):
        if not hasattr(self, "_Init"):
            self._InitWorker(Workspace, MetaFile, Target, Toolchain, Arch, *args)
            self._Init = True

    ## Cache the timestamps of metafiles of every module in a class attribute
    #
    TimeDict = {}

    def __new__(cls, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):
#         check if this module is employed by active platform
        if not PlatformInfo(Workspace, args[0], Target, Toolchain, Arch,args[-1]).ValidModule(MetaFile):
            EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \
                              % (MetaFile, Arch))
            return None
        return super(ModuleAutoGen, cls).__new__(cls, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs)

    ## Initialize ModuleAutoGen
    #
    #   @param      Workspace           EdkIIWorkspaceBuild object
    #   @param      ModuleFile          The path of module file
    #   @param      Target              Build target (DEBUG, RELEASE)
    #   @param      Toolchain           Name of tool chain
    #   @param      Arch                The arch the module supports
    #   @param      PlatformFile        Platform meta-file
    #
    def _InitWorker(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile,DataPipe):
        EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch))
        GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target)

        self.Workspace = Workspace
        self.WorkspaceDir = ""
        self.PlatformInfo = None
        self.DataPipe = DataPipe
        self.__init_platform_info__()
        self.MetaFile = ModuleFile
        self.SourceDir = self.MetaFile.SubDir
        self.SourceDir = mws.relpath(self.SourceDir, self.WorkspaceDir)

        self.ToolChain = Toolchain
        self.BuildTarget = Target
        self.Arch = Arch
        self.ToolChainFamily = self.PlatformInfo.ToolChainFamily
        self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily

        self.IsCodeFileCreated = False
        self.IsAsBuiltInfCreated = False
        self.DepexGenerated = False

        self.BuildDatabase = self.Workspace.BuildDatabase
        self.BuildRuleOrder = None
        self.BuildTime      = 0

        self._GuidComments = OrderedListDict()
        self._ProtocolComments = OrderedListDict()
        self._PpiComments = OrderedListDict()
        self._BuildTargets            = None
        self._IntroBuildTargetList    = None
        self._FinalBuildTargetList    = None
        self._FileTypes               = None

        self.AutoGenDepSet = set()
        self.ReferenceModules = []
        self.ConstPcd                  = {}
        self.FileDependCache  = {}

    def __init_platform_info__(self):
        pinfo = self.DataPipe.Get("P_Info")
        self.WorkspaceDir = pinfo.get("WorkspaceDir")
        self.PlatformInfo = PlatformInfo(self.Workspace,pinfo.get("ActivePlatform"),pinfo.get("Target"),pinfo.get("ToolChain"),pinfo.get("Arch"),self.DataPipe)
    ## hash() operator of ModuleAutoGen
    #
    #  The module file path and arch string will be used to represent
    #  hash value of this object
    #
    #   @retval   int Hash value of the module file path and arch
    #
    @cached_class_function
    def __hash__(self):
        return hash((self.MetaFile, self.Arch, self.ToolChain,self.BuildTarget))
    def __repr__(self):
        return "%s [%s]" % (self.MetaFile, self.Arch)

    # Get FixedAtBuild Pcds of this Module
    @cached_property
    def FixedAtBuildPcds(self):
        RetVal = []
        for Pcd in self.ModulePcdList:
            if Pcd.Type != TAB_PCDS_FIXED_AT_BUILD:
                continue
            if Pcd not in RetVal:
                RetVal.append(Pcd)
        return RetVal

    @cached_property
    def FixedVoidTypePcds(self):
        RetVal = {}
        for Pcd in self.FixedAtBuildPcds:
            if Pcd.DatumType == TAB_VOID:
                if '.'.join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName)) not in RetVal:
                    RetVal['.'.join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName))] = Pcd.DefaultValue
        return RetVal

    @property
    def UniqueBaseName(self):
        ModuleNames = self.DataPipe.Get("M_Name")
        if not ModuleNames:
            return self.Name
        return ModuleNames.get((self.Name,self.MetaFile),self.Name)

    # Macros could be used in build_rule.txt (also Makefile)
    @cached_property
    def Macros(self):
        return OrderedDict((
            ("WORKSPACE" ,self.WorkspaceDir),
            ("MODULE_NAME" ,self.Name),
            ("MODULE_NAME_GUID" ,self.UniqueBaseName),
            ("MODULE_GUID" ,self.Guid),
            ("MODULE_VERSION" ,self.Version),
            ("MODULE_TYPE" ,self.ModuleType),
            ("MODULE_FILE" ,str(self.MetaFile)),
            ("MODULE_FILE_BASE_NAME" ,self.MetaFile.BaseName),
            ("MODULE_RELATIVE_DIR" ,self.SourceDir),
            ("MODULE_DIR" ,self.SourceDir),
            ("BASE_NAME" ,self.Name),
            ("ARCH" ,self.Arch),
            ("TOOLCHAIN" ,self.ToolChain),
            ("TOOLCHAIN_TAG" ,self.ToolChain),
            ("TOOL_CHAIN_TAG" ,self.ToolChain),
            ("TARGET" ,self.BuildTarget),
            ("BUILD_DIR" ,self.PlatformInfo.BuildDir),
            ("BIN_DIR" ,os.path.join(self.PlatformInfo.BuildDir, self.Arch)),
            ("LIB_DIR" ,os.path.join(self.PlatformInfo.BuildDir, self.Arch)),
            ("MODULE_BUILD_DIR" ,self.BuildDir),
            ("OUTPUT_DIR" ,self.OutputDir),
            ("DEBUG_DIR" ,self.DebugDir),
            ("DEST_DIR_OUTPUT" ,self.OutputDir),
            ("DEST_DIR_DEBUG" ,self.DebugDir),
            ("PLATFORM_NAME" ,self.PlatformInfo.Name),
            ("PLATFORM_GUID" ,self.PlatformInfo.Guid),
            ("PLATFORM_VERSION" ,self.PlatformInfo.Version),
            ("PLATFORM_RELATIVE_DIR" ,self.PlatformInfo.SourceDir),
            ("PLATFORM_DIR" ,mws.join(self.WorkspaceDir, self.PlatformInfo.SourceDir)),
            ("PLATFORM_OUTPUT_DIR" ,self.PlatformInfo.OutputDir),
            ("FFS_OUTPUT_DIR" ,self.FfsOutputDir)
            ))

    ## Return the module build data object
    @cached_property
    def Module(self):
        return self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]

    ## Return the module name
    @cached_property
    def Name(self):
        return self.Module.BaseName

    ## Return the module DxsFile if exist
    @cached_property
    def DxsFile(self):
        return self.Module.DxsFile

    ## Return the module meta-file GUID
    @cached_property
    def Guid(self):
        #
        # To build same module more than once, the module path with FILE_GUID overridden has
        # the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the real path
        # in DSC. The overridden GUID can be retrieved from file name
        #
        if os.path.basename(self.MetaFile.File) != os.path.basename(self.MetaFile.Path):
            #
            # Length of GUID is 36
            #
            return os.path.basename(self.MetaFile.Path)[:36]
        return self.Module.Guid

    ## Return the module version
    @cached_property
    def Version(self):
        return self.Module.Version

    ## Return the module type
    @cached_property
    def ModuleType(self):
        return self.Module.ModuleType

    ## Return the component type (for Edk.x style of module)
    @cached_property
    def ComponentType(self):
        return self.Module.ComponentType

    ## Return the build type
    @cached_property
    def BuildType(self):
        return self.Module.BuildType

    ## Return the PCD_IS_DRIVER setting
    @cached_property
    def PcdIsDriver(self):
        return self.Module.PcdIsDriver

    ## Return the autogen version, i.e. module meta-file version
    @cached_property
    def AutoGenVersion(self):
        return self.Module.AutoGenVersion

    ## Check if the module is library or not
    @cached_property
    def IsLibrary(self):
        return bool(self.Module.LibraryClass)

    ## Check if the module is binary module or not
    @cached_property
    def IsBinaryModule(self):
        return self.Module.IsBinaryModule

    ## Return the directory to store intermediate files of the module
    @cached_property
    def BuildDir(self):
        return _MakeDir((
                                    self.PlatformInfo.BuildDir,
                                    self.Arch,
                                    self.SourceDir,
                                    self.MetaFile.BaseName
            ))

    ## Return the directory to store the intermediate object files of the module
    @cached_property
    def OutputDir(self):
        return _MakeDir((self.BuildDir, "OUTPUT"))

    ## Return the directory path to store ffs file
    @cached_property
    def FfsOutputDir(self):
        if GlobalData.gFdfParser:
            return path.join(self.PlatformInfo.BuildDir, TAB_FV_DIRECTORY, "Ffs", self.Guid + self.Name)
        return ''

    ## Return the directory to store auto-gened source files of the module
    @cached_property
    def DebugDir(self):
        return _MakeDir((self.BuildDir, "DEBUG"))

    ## Return the path of custom file
    @cached_property
    def CustomMakefile(self):
        RetVal = {}
        for Type in self.Module.CustomMakefile:
            MakeType = gMakeTypeMap[Type] if Type in gMakeTypeMap else 'nmake'
            File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
            RetVal[MakeType] = File
        return RetVal

    ## Return the directory of the makefile
    #
    #   @retval     string  The directory string of module's makefile
    #
    @cached_property
    def MakeFileDir(self):
        return self.BuildDir

    ## Return build command string
    #
    #   @retval     string  Build command string
    #
    @cached_property
    def BuildCommand(self):
        return self.PlatformInfo.BuildCommand

    ## Get Module package and Platform package
    #
    #   @retval list The list of package object
    #
    @cached_property
    def PackageList(self):
        PkagList = []
        if self.Module.Packages:
            PkagList.extend(self.Module.Packages)
        Platform = self.BuildDatabase[self.PlatformInfo.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]
        for Package in Platform.Packages:
            if Package in PkagList:
                continue
            PkagList.append(Package)
        return PkagList

    ## Get object list of all packages the module and its dependent libraries belong to and the Platform depends on
    #
    #   @retval     list    The list of package object
    #
    @cached_property
    def DerivedPackageList(self):
        PackageList = []
        PackageList.extend(self.PackageList)
        for M in self.DependentLibraryList:
            for Package in M.Packages:
                if Package in PackageList:
                    continue
                PackageList.append(Package)
        return PackageList

    ## Get the depex string
    #
    # @return : a string contain all depex expression.
    def _GetDepexExpresionString(self):
        DepexStr = ''
        DepexList = []
        ## DPX_SOURCE IN Define section.
        if self.Module.DxsFile:
            return DepexStr
        for M in [self.Module] + self.DependentLibraryList:
            Filename = M.MetaFile.Path
            InfObj = InfSectionParser.InfSectionParser(Filename)
            DepexExpressionList = InfObj.GetDepexExpresionList()
            for DepexExpression in DepexExpressionList:
                for key in DepexExpression:
                    Arch, ModuleType = key
                    DepexExpr = [x for x in DepexExpression[key] if not str(x).startswith('#')]
                    # the type of build module is USER_DEFINED.
                    # All different DEPEX section tags would be copied into the As Built INF file
                    # and there would be separate DEPEX section tags
                    if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED or self.ModuleType.upper() == SUP_MODULE_HOST_APPLICATION:
                        if (Arch.upper() == self.Arch.upper()) and (ModuleType.upper() != TAB_ARCH_COMMON):
                            DepexList.append({(Arch, ModuleType): DepexExpr})
                    else:
                        if Arch.upper() == TAB_ARCH_COMMON or \
                          (Arch.upper() == self.Arch.upper() and \
                          ModuleType.upper() in [TAB_ARCH_COMMON, self.ModuleType.upper()]):
                            DepexList.append({(Arch, ModuleType): DepexExpr})

        #the type of build module is USER_DEFINED.
        if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED or self.ModuleType.upper() == SUP_MODULE_HOST_APPLICATION:
            for Depex in DepexList:
                for key in Depex:
                    DepexStr += '[Depex.%s.%s]\n' % key
                    DepexStr += '\n'.join('# '+ val for val in Depex[key])
                    DepexStr += '\n\n'
            if not DepexStr:
                return '[Depex.%s]\n' % self.Arch
            return DepexStr

        #the type of build module not is USER_DEFINED.
        Count = 0
        for Depex in DepexList:
            Count += 1
            if DepexStr != '':
                DepexStr += ' AND '
            DepexStr += '('
            for D in Depex.values():
                DepexStr += ' '.join(val for val in D)
            Index = DepexStr.find('END')
            if Index > -1 and Index == len(DepexStr) - 3:
                DepexStr = DepexStr[:-3]
            DepexStr = DepexStr.strip()
            DepexStr += ')'
        if Count == 1:
            DepexStr = DepexStr.lstrip('(').rstrip(')').strip()
        if not DepexStr:
            return '[Depex.%s]\n' % self.Arch
        return '[Depex.%s]\n#  ' % self.Arch + DepexStr

    ## Merge dependency expression
    #
    #   @retval     list    The token list of the dependency expression after parsed
    #
    @cached_property
    def DepexList(self):
        if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
            return {}

        DepexList = []
        #
        # Append depex from dependent libraries, if not "BEFORE", "AFTER" expression
        #
        FixedVoidTypePcds = {}
        for M in [self] + self.LibraryAutoGenList:
            FixedVoidTypePcds.update(M.FixedVoidTypePcds)
        for M in [self] + self.LibraryAutoGenList:
            Inherited = False
            for D in M.Module.Depex[self.Arch, self.ModuleType]:
                if DepexList != []:
                    DepexList.append('AND')
                DepexList.append('(')
                #replace D with value if D is FixedAtBuild PCD
                NewList = []
                for item in D:
                    if '.' not in item:
                        NewList.append(item)
                    else:
                        try:
                            Value = FixedVoidTypePcds[item]
                            if len(Value.split(',')) != 16:
                                EdkLogger.error("build", FORMAT_INVALID,
                                                "{} used in [Depex] section should be used as FixedAtBuild type and VOID* datum type and 16 bytes in the module.".format(item))
                            NewList.append(Value)
                        except:
                            EdkLogger.error("build", FORMAT_INVALID, "{} used in [Depex] section should be used as FixedAtBuild type and VOID* datum type in the module.".format(item))

                DepexList.extend(NewList)
                if DepexList[-1] == 'END':  # no need of a END at this time
                    DepexList.pop()
                DepexList.append(')')
                Inherited = True
            if Inherited:
                EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.Module.BaseName, DepexList))
            if 'BEFORE' in DepexList or 'AFTER' in DepexList:
                break
            if len(DepexList) > 0:
                EdkLogger.verbose('')
        return {self.ModuleType:DepexList}

    ## Merge dependency expression
    #
    #   @retval     list    The token list of the dependency expression after parsed
    #
    @cached_property
    def DepexExpressionDict(self):
        if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
            return {}

        DepexExpressionString = ''
        #
        # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
        #
        for M in [self.Module] + self.DependentLibraryList:
            Inherited = False
            for D in M.DepexExpression[self.Arch, self.ModuleType]:
                if DepexExpressionString != '':
                    DepexExpressionString += ' AND '
                DepexExpressionString += '('
                DepexExpressionString += D
                DepexExpressionString = DepexExpressionString.rstrip('END').strip()
                DepexExpressionString += ')'
                Inherited = True
            if Inherited:
                EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexExpressionString))
            if 'BEFORE' in DepexExpressionString or 'AFTER' in DepexExpressionString:
                break
        if len(DepexExpressionString) > 0:
            EdkLogger.verbose('')

        return {self.ModuleType:DepexExpressionString}

    # Get the tiano core user extension, it is contain dependent library.
    # @retval: a list contain tiano core userextension.
    #
    def _GetTianoCoreUserExtensionList(self):
        TianoCoreUserExtentionList = []
        for M in [self.Module] + self.DependentLibraryList:
            Filename = M.MetaFile.Path
            InfObj = InfSectionParser.InfSectionParser(Filename)
            TianoCoreUserExtenList = InfObj.GetUserExtensionTianoCore()
            for TianoCoreUserExtent in TianoCoreUserExtenList:
                for Section in TianoCoreUserExtent:
                    ItemList = Section.split(TAB_SPLIT)
                    Arch = self.Arch
                    if len(ItemList) == 4:
                        Arch = ItemList[3]
                    if Arch.upper() == TAB_ARCH_COMMON or Arch.upper() == self.Arch.upper():
                        TianoCoreList = []
                        TianoCoreList.extend([TAB_SECTION_START + Section + TAB_SECTION_END])
                        TianoCoreList.extend(TianoCoreUserExtent[Section][:])
                        TianoCoreList.append('\n')
                        TianoCoreUserExtentionList.append(TianoCoreList)

        return TianoCoreUserExtentionList

    ## Return the list of specification version required for the module
    #
    #   @retval     list    The list of specification defined in module file
    #
    @cached_property
    def Specification(self):
        return self.Module.Specification

    ## Tool option for the module build
    #
    #   @param      PlatformInfo    The object of PlatformBuildInfo
    #   @retval     dict            The dict containing valid options
    #
    @cached_property
    def BuildOption(self):
        RetVal, self.BuildRuleOrder = self.PlatformInfo.ApplyBuildOption(self.Module)
        if self.BuildRuleOrder:
            self.BuildRuleOrder = ['.%s' % Ext for Ext in self.BuildRuleOrder.split()]
        return RetVal

    ## Get include path list from tool option for the module build
    #
    #   @retval     list            The include path list
    #
    @cached_property
    def BuildOptionIncPathList(self):
        #
        # Regular expression for finding Include Directories, the difference between MSFT and INTEL/GCC/RVCT
        # is the former use /I , the Latter used -I to specify include directories
        #
        if self.PlatformInfo.ToolChainFamily in (TAB_COMPILER_MSFT):
            BuildOptIncludeRegEx = gBuildOptIncludePatternMsft
        elif self.PlatformInfo.ToolChainFamily in ('INTEL', 'GCC', 'RVCT'):
            BuildOptIncludeRegEx = gBuildOptIncludePatternOther
        else:
            #
            # New ToolChainFamily, don't known whether there is option to specify include directories
            #
            return []

        RetVal = []
        for Tool in ('CC', 'PP', 'VFRPP', 'ASLPP', 'ASLCC', 'APP', 'ASM'):
            try:
                FlagOption = self.BuildOption[Tool]['FLAGS']
            except KeyError:
                FlagOption = ''

            if self.ToolChainFamily != 'RVCT':
                IncPathList = [NormPath(Path, self.Macros) for Path in BuildOptIncludeRegEx.findall(FlagOption)]
            else:
                #
                # RVCT may specify a list of directory seperated by commas
                #
                IncPathList = []
                for Path in BuildOptIncludeRegEx.findall(FlagOption):
                    PathList = GetSplitList(Path, TAB_COMMA_SPLIT)
                    IncPathList.extend(NormPath(PathEntry, self.Macros) for PathEntry in PathList)

            #
            # EDK II modules must not reference header files outside of the packages they depend on or
            # within the module's directory tree. Report error if violation.
            #
            if GlobalData.gDisableIncludePathCheck == False:
                for Path in IncPathList:
                    if (Path not in self.IncludePathList) and (CommonPath([Path, self.MetaFile.Dir]) != self.MetaFile.Dir):
                        ErrMsg = "The include directory for the EDK II module in this line is invalid %s specified in %s FLAGS '%s'" % (Path, Tool, FlagOption)
                        EdkLogger.error("build",
                                        PARAMETER_INVALID,
                                        ExtraData=ErrMsg,
                                        File=str(self.MetaFile))
            RetVal += IncPathList
        return RetVal

    ## Return a list of files which can be built from source
    #
    #  What kind of files can be built is determined by build rules in
    #  $(CONF_DIRECTORY)/build_rule.txt and toolchain family.
    #
    @cached_property
    def SourceFileList(self):
        RetVal = []
        ToolChainTagSet = {"", TAB_STAR, self.ToolChain}
        ToolChainFamilySet = {"", TAB_STAR, self.ToolChainFamily, self.BuildRuleFamily}
        for F in self.Module.Sources:
            # match tool chain
            if F.TagName not in ToolChainTagSet:
                EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, "
                                "but [%s] is currently used" % (F.TagName, str(F), self.ToolChain))
                continue
            # match tool chain family or build rule family
            if F.ToolChainFamily not in ToolChainFamilySet:
                EdkLogger.debug(
                            EdkLogger.DEBUG_0,
                            "The file [%s] must be built by tools of [%s], " \
                            "but current toolchain family is [%s], buildrule family is [%s]" \
                                % (str(F), F.ToolChainFamily, self.ToolChainFamily, self.BuildRuleFamily))
                continue

            # add the file path into search path list for file including
            if F.Dir not in self.IncludePathList:
                self.IncludePathList.insert(0, F.Dir)
            RetVal.append(F)

        self._MatchBuildRuleOrder(RetVal)

        for F in RetVal:
            self._ApplyBuildRule(F, TAB_UNKNOWN_FILE)
        return RetVal

    def _MatchBuildRuleOrder(self, FileList):
        Order_Dict = {}
        self.BuildOption
        for SingleFile in FileList:
            if self.BuildRuleOrder and SingleFile.Ext in self.BuildRuleOrder and SingleFile.Ext in self.BuildRules:
                key = SingleFile.Path.rsplit(SingleFile.Ext,1)[0]
                if key in Order_Dict:
                    Order_Dict[key].append(SingleFile.Ext)
                else:
                    Order_Dict[key] = [SingleFile.Ext]

        RemoveList = []
        for F in Order_Dict:
            if len(Order_Dict[F]) > 1:
                Order_Dict[F].sort(key=lambda i: self.BuildRuleOrder.index(i))
                for Ext in Order_Dict[F][1:]:
                    RemoveList.append(F + Ext)

        for item in RemoveList:
            FileList.remove(item)

        return FileList

    ## Return the list of unicode files
    @cached_property
    def UnicodeFileList(self):
        return self.FileTypes.get(TAB_UNICODE_FILE,[])

    ## Return the list of vfr files
    @cached_property
    def VfrFileList(self):
        return self.FileTypes.get(TAB_VFR_FILE, [])

    ## Return the list of Image Definition files
    @cached_property
    def IdfFileList(self):
        return self.FileTypes.get(TAB_IMAGE_FILE,[])

    ## Return a list of files which can be built from binary
    #
    #  "Build" binary files are just to copy them to build directory.
    #
    #   @retval     list            The list of files which can be built later
    #
    @cached_property
    def BinaryFileList(self):
        RetVal = []
        for F in self.Module.Binaries:
            if F.Target not in [TAB_ARCH_COMMON, TAB_STAR] and F.Target != self.BuildTarget:
                continue
            RetVal.append(F)
            self._ApplyBuildRule(F, F.Type, BinaryFileList=RetVal)
        return RetVal

    @cached_property
    def BuildRules(self):
        RetVal = {}
        BuildRuleDatabase = self.PlatformInfo.BuildRule
        for Type in BuildRuleDatabase.FileTypeList:
            #first try getting build rule by BuildRuleFamily
            RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.BuildRuleFamily]
            if not RuleObject:
                # build type is always module type, but ...
                if self.ModuleType != self.BuildType:
                    RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.BuildRuleFamily]
            #second try getting build rule by ToolChainFamily
            if not RuleObject:
                RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.ToolChainFamily]
                if not RuleObject:
                    # build type is always module type, but ...
                    if self.ModuleType != self.BuildType:
                        RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.ToolChainFamily]
            if not RuleObject:
                continue
            RuleObject = RuleObject.Instantiate(self.Macros)
            RetVal[Type] = RuleObject
            for Ext in RuleObject.SourceFileExtList:
                RetVal[Ext] = RuleObject
        return RetVal

    def _ApplyBuildRule(self, File, FileType, BinaryFileList=None):
        if self._BuildTargets is None:
            self._IntroBuildTargetList = set()
            self._FinalBuildTargetList = set()
            self._BuildTargets = defaultdict(set)
            self._FileTypes = defaultdict(set)

        if not BinaryFileList:
            BinaryFileList = self.BinaryFileList

        SubDirectory = os.path.join(self.OutputDir, File.SubDir)
        if not os.path.exists(SubDirectory):
            CreateDirectory(SubDirectory)
        TargetList = set()
        FinalTargetName = set()
        RuleChain = set()
        SourceList = [File]
        Index = 0
        #
        # Make sure to get build rule order value
        #
        self.BuildOption

        while Index < len(SourceList):
            # Reset the FileType if not the first iteration.
            if Index > 0:
                FileType = TAB_UNKNOWN_FILE
            Source = SourceList[Index]
            Index = Index + 1

            if Source != File:
                CreateDirectory(Source.Dir)

            if File.IsBinary and File == Source and File in BinaryFileList:
                # Skip all files that are not binary libraries
                if not self.IsLibrary:
                    continue
                RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]
            elif FileType in self.BuildRules:
                RuleObject = self.BuildRules[FileType]
            elif Source.Ext in self.BuildRules:
                RuleObject = self.BuildRules[Source.Ext]
            else:
                # No more rule to apply: Source is a final target.
                FinalTargetName.add(Source)
                continue

            FileType = RuleObject.SourceFileType
            self._FileTypes[FileType].add(Source)

            # stop at STATIC_LIBRARY for library
            if self.IsLibrary and FileType == TAB_STATIC_LIBRARY:
                FinalTargetName.add(Source)
                continue

            Target = RuleObject.Apply(Source, self.BuildRuleOrder)
            if not Target:
                # No Target: Source is a final target.
                FinalTargetName.add(Source)
                continue

            TargetList.add(Target)
            self._BuildTargets[FileType].add(Target)

            if not Source.IsBinary and Source == File:
                self._IntroBuildTargetList.add(Target)

            # to avoid cyclic rule
            if FileType in RuleChain:
                EdkLogger.error("build", ERROR_STATEMENT, "Cyclic dependency detected while generating rule for %s" % str(Source))

            RuleChain.add(FileType)
            SourceList.extend(Target.Outputs)

        # For each final target name, retrieve the corresponding TargetDescBlock instance.
        for FTargetName in FinalTargetName:
            for Target in TargetList:
                if FTargetName == Target.Target:
                    self._FinalBuildTargetList.add(Target)

    @cached_property
    def Targets(self):
        if self._BuildTargets is None:
            self._IntroBuildTargetList = set()
            self._FinalBuildTargetList = set()
            self._BuildTargets = defaultdict(set)
            self._FileTypes = defaultdict(set)

        #TRICK: call SourceFileList property to apply build rule for source files
        self.SourceFileList

        #TRICK: call _GetBinaryFileList to apply build rule for binary files
        self.BinaryFileList

        return self._BuildTargets

    @cached_property
    def IntroTargetList(self):
        self.Targets
        return self._IntroBuildTargetList

    @cached_property
    def CodaTargetList(self):
        self.Targets
        return self._FinalBuildTargetList

    @cached_property
    def FileTypes(self):
        self.Targets
        return self._FileTypes

    ## Get the list of package object the module depends on and the Platform depends on
    #
    #   @retval     list    The package object list
    #
    @cached_property
    def DependentPackageList(self):
        return self.PackageList

    ## Return the list of auto-generated code file
    #
    #   @retval     list        The list of auto-generated file
    #
    @cached_property
    def AutoGenFileList(self):
        AutoGenUniIdf = self.BuildType != 'UEFI_HII'
        UniStringBinBuffer = BytesIO()
        IdfGenBinBuffer = BytesIO()
        RetVal = {}
        AutoGenC = TemplateString()
        AutoGenH = TemplateString()
        StringH = TemplateString()
        StringIdf = TemplateString()
        GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, AutoGenUniIdf, UniStringBinBuffer, StringIdf, AutoGenUniIdf, IdfGenBinBuffer)
        #
        # AutoGen.c is generated if there are library classes in inf, or there are object files
        #
        if str(AutoGenC) != "" and (len(self.Module.LibraryClasses) > 0
                                    or TAB_OBJECT_FILE in self.FileTypes):
            AutoFile = PathClass(gAutoGenCodeFileName, self.DebugDir)
            RetVal[AutoFile] = str(AutoGenC)
            self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
        if str(AutoGenH) != "":
            AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir)
            RetVal[AutoFile] = str(AutoGenH)
            self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
        if str(StringH) != "":
            AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir)
            RetVal[AutoFile] = str(StringH)
            self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
        if UniStringBinBuffer is not None and UniStringBinBuffer.getvalue() != b"":
            AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)
            RetVal[AutoFile] = UniStringBinBuffer.getvalue()
            AutoFile.IsBinary = True
            self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
        if UniStringBinBuffer is not None:
            UniStringBinBuffer.close()
        if str(StringIdf) != "":
            AutoFile = PathClass(gAutoGenImageDefFileName % {"module_name":self.Name}, self.DebugDir)
            RetVal[AutoFile] = str(StringIdf)
            self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
        if IdfGenBinBuffer is not None and IdfGenBinBuffer.getvalue() != b"":
            AutoFile = PathClass(gAutoGenIdfFileName % {"module_name":self.Name}, self.OutputDir)
            RetVal[AutoFile] = IdfGenBinBuffer.getvalue()
            AutoFile.IsBinary = True
            self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
        if IdfGenBinBuffer is not None:
            IdfGenBinBuffer.close()
        return RetVal

    ## Return the list of library modules explicitly or implicitly used by this module
    @cached_property
    def DependentLibraryList(self):
        # only merge library classes and PCD for non-library module
        if self.IsLibrary:
            return []
        return self.PlatformInfo.ApplyLibraryInstance(self.Module)

    ## Get the list of PCDs from current module
    #
    #   @retval     list                    The list of PCD
    #
    @cached_property
    def ModulePcdList(self):
        # apply PCD settings from platform
        RetVal = self.PlatformInfo.ApplyPcdSetting(self, self.Module.Pcds)

        return RetVal
    @cached_property
    def _PcdComments(self):
        ReVal = OrderedListDict()
        ExtendCopyDictionaryLists(ReVal, self.Module.PcdComments)
        if not self.IsLibrary:
            for Library in self.DependentLibraryList:
                ExtendCopyDictionaryLists(ReVal, Library.PcdComments)
        return ReVal

    ## Get the list of PCDs from dependent libraries
    #
    #   @retval     list                    The list of PCD
    #
    @cached_property
    def LibraryPcdList(self):
        if self.IsLibrary:
            return []
        RetVal = []
        Pcds = set()
        # get PCDs from dependent libraries
        for Library in self.DependentLibraryList:
            PcdsInLibrary = OrderedDict()
            for Key in Library.Pcds:
                # skip duplicated PCDs
                if Key in self.Module.Pcds or Key in Pcds:
                    continue
                Pcds.add(Key)
                PcdsInLibrary[Key] = copy.copy(Library.Pcds[Key])
            RetVal.extend(self.PlatformInfo.ApplyPcdSetting(self, PcdsInLibrary, Library=Library))
        return RetVal

    ## Get the GUID value mapping
    #
    #   @retval     dict    The mapping between GUID cname and its value
    #
    @cached_property
    def GuidList(self):
        RetVal = self.Module.Guids
        for Library in self.DependentLibraryList:
            RetVal.update(Library.Guids)
            ExtendCopyDictionaryLists(self._GuidComments, Library.GuidComments)
        ExtendCopyDictionaryLists(self._GuidComments, self.Module.GuidComments)
        return RetVal

    @cached_property
    def GetGuidsUsedByPcd(self):
        RetVal = OrderedDict(self.Module.GetGuidsUsedByPcd())
        for Library in self.DependentLibraryList:
            RetVal.update(Library.GetGuidsUsedByPcd())
        return RetVal
    ## Get the protocol value mapping
    #
    #   @retval     dict    The mapping between protocol cname and its value
    #
    @cached_property
    def ProtocolList(self):
        RetVal = OrderedDict(self.Module.Protocols)
        for Library in self.DependentLibraryList:
            RetVal.update(Library.Protocols)
            ExtendCopyDictionaryLists(self._ProtocolComments, Library.ProtocolComments)
        ExtendCopyDictionaryLists(self._ProtocolComments, self.Module.ProtocolComments)
        return RetVal

    ## Get the PPI value mapping
    #
    #   @retval     dict    The mapping between PPI cname and its value
    #
    @cached_property
    def PpiList(self):
        RetVal = OrderedDict(self.Module.Ppis)
        for Library in self.DependentLibraryList:
            RetVal.update(Library.Ppis)
            ExtendCopyDictionaryLists(self._PpiComments, Library.PpiComments)
        ExtendCopyDictionaryLists(self._PpiComments, self.Module.PpiComments)
        return RetVal

    ## Get the list of include search path
    #
    #   @retval     list                    The list path
    #
    @cached_property
    def IncludePathList(self):
        RetVal = []
        RetVal.append(self.MetaFile.Dir)
        RetVal.append(self.DebugDir)

        for Package in self.PackageList:
            PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir)
            if PackageDir not in RetVal:
                RetVal.append(PackageDir)
            IncludesList = Package.Includes
            if Package._PrivateIncludes:
                if not self.MetaFile.OriginalPath.Path.startswith(PackageDir):
                    IncludesList = list(set(Package.Includes).difference(set(Package._PrivateIncludes)))
            for Inc in IncludesList:
                if Inc not in RetVal:
                    RetVal.append(str(Inc))
        RetVal.extend(self.IncPathFromBuildOptions)
        return RetVal

    @cached_property
    def IncPathFromBuildOptions(self):
        IncPathList = []
        for tool in self.BuildOption:
            if 'FLAGS' in self.BuildOption[tool]:
                flags = self.BuildOption[tool]['FLAGS']
                whitespace = False
                for flag in flags.split(" "):
                    flag = flag.strip()
                    if flag.startswith(("/I","-I")):
                        if len(flag)>2:
                            if os.path.exists(flag[2:]):
                                IncPathList.append(flag[2:])
                        else:
                            whitespace = True
                            continue
                    if whitespace and flag:
                        if os.path.exists(flag):
                            IncPathList.append(flag)
                            whitespace = False
        return IncPathList

    @cached_property
    def IncludePathLength(self):
        return sum(len(inc)+1 for inc in self.IncludePathList)

    ## Get the list of include paths from the packages
    #
    #   @IncludesList     list             The list path
    #
    @cached_property
    def PackageIncludePathList(self):
        IncludesList = []
        for Package in self.PackageList:
            PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir)
            IncludesList = Package.Includes
            if Package._PrivateIncludes:
                if not self.MetaFile.Path.startswith(PackageDir):
                    IncludesList = list(set(Package.Includes).difference(set(Package._PrivateIncludes)))
        return IncludesList

    ## Get HII EX PCDs which maybe used by VFR
    #
    #  efivarstore used by VFR may relate with HII EX PCDs
    #  Get the variable name and GUID from efivarstore and HII EX PCD
    #  List the HII EX PCDs in As Built INF if both name and GUID match.
    #
    #  @retval    list    HII EX PCDs
    #
    def _GetPcdsMaybeUsedByVfr(self):
        if not self.SourceFileList:
            return []

        NameGuids = set()
        for SrcFile in self.SourceFileList:
            if SrcFile.Ext.lower() != '.vfr':
                continue
            Vfri = os.path.join(self.OutputDir, SrcFile.BaseName + '.i')
            if not os.path.exists(Vfri):
                continue
            VfriFile = open(Vfri, 'r')
            Content = VfriFile.read()
            VfriFile.close()
            Pos = Content.find('efivarstore')
            while Pos != -1:
                #
                # Make sure 'efivarstore' is the start of efivarstore statement
                # In case of the value of 'name' (name = efivarstore) is equal to 'efivarstore'
                #
                Index = Pos - 1
                while Index >= 0 and Content[Index] in ' \t\r\n':
                    Index -= 1
                if Index >= 0 and Content[Index] != ';':
                    Pos = Content.find('efivarstore', Pos + len('efivarstore'))
                    continue
                #
                # 'efivarstore' must be followed by name and guid
                #
                Name = gEfiVarStoreNamePattern.search(Content, Pos)
                if not Name:
                    break
                Guid = gEfiVarStoreGuidPattern.search(Content, Pos)
                if not Guid:
                    break
                NameArray = _ConvertStringToByteArray('L"' + Name.group(1) + '"')
                NameGuids.add((NameArray, GuidStructureStringToGuidString(Guid.group(1))))
                Pos = Content.find('efivarstore', Name.end())
        if not NameGuids:
            return []
        HiiExPcds = []
        for Pcd in self.PlatformInfo.Pcds.values():
            if Pcd.Type != TAB_PCDS_DYNAMIC_EX_HII:
                continue
            for SkuInfo in Pcd.SkuInfoList.values():
                Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList, self.MetaFile.Path)
                if not Value:
                    continue
                Name = _ConvertStringToByteArray(SkuInfo.VariableName)
                Guid = GuidStructureStringToGuidString(Value)
                if (Name, Guid) in NameGuids and Pcd not in HiiExPcds:
                    HiiExPcds.append(Pcd)
                    break

        return HiiExPcds

    def _GenOffsetBin(self):
        VfrUniBaseName = {}
        for SourceFile in self.Module.Sources:
            if SourceFile.Type.upper() == ".VFR" :
                #
                # search the .map file to find the offset of vfr binary in the PE32+/TE file.
                #
                VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")
            elif SourceFile.Type.upper() == ".UNI" :
                #
                # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
                #
                VfrUniBaseName["UniOffsetName"] = (self.Name + "Strings")

        if not VfrUniBaseName:
            return None
        MapFileName = os.path.join(self.OutputDir, self.Name + ".map")
        EfiFileName = os.path.join(self.OutputDir, self.Name + ".efi")
        VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, list(VfrUniBaseName.values()))
        if not VfrUniOffsetList:
            return None

        OutputName = '%sOffset.bin' % self.Name
        UniVfrOffsetFileName    =  os.path.join( self.OutputDir, OutputName)

        try:
            fInputfile = open(UniVfrOffsetFileName, "wb+", 0)
        except:
            EdkLogger.error("build", FILE_OPEN_FAILURE, "File open failed for %s" % UniVfrOffsetFileName, None)

        # Use a instance of BytesIO to cache data
        fStringIO = BytesIO()

        for Item in VfrUniOffsetList:
            if (Item[0].find("Strings") != -1):
                #
                # UNI offset in image.
                # GUID + Offset
                # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
                #
                UniGuid = b'\xe0\xc5\x13\x89\xf63\x86M\x9b\xf1C\xef\x89\xfc\x06f'
                fStringIO.write(UniGuid)
                UniValue = pack ('Q', int (Item[1], 16))
                fStringIO.write (UniValue)
            else:
                #
                # VFR binary offset in image.
                # GUID + Offset
                # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
                #
                VfrGuid = b'\xb4|\xbc\xd0Gj_I\xaa\x11q\x07F\xda\x06\xa2'
                fStringIO.write(VfrGuid)
                VfrValue = pack ('Q', int (Item[1], 16))
                fStringIO.write (VfrValue)
        #
        # write data into file.
        #
        try :
            fInputfile.write (fStringIO.getvalue())
        except:
            EdkLogger.error("build", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the "
                            "file been locked or using by other applications." %UniVfrOffsetFileName, None)

        fStringIO.close ()
        fInputfile.close ()
        return OutputName

    @cached_property
    def OutputFile(self):
        retVal = set()

        for Root, Dirs, Files in os.walk(self.BuildDir):
            for File in Files:
                # lib file is already added through above CodaTargetList, skip it here
                if not (File.lower().endswith('.obj') or File.lower().endswith('.debug')):
                    NewFile = path.join(Root, File)
                    retVal.add(NewFile)

        for Root, Dirs, Files in os.walk(self.FfsOutputDir):
            for File in Files:
                NewFile = path.join(Root, File)
                retVal.add(NewFile)

        return retVal

    ## Create AsBuilt INF file the module
    #
    def CreateAsBuiltInf(self):

        if self.IsAsBuiltInfCreated:
            return

        # Skip INF file generation for libraries
        if self.IsLibrary:
            return

        # Skip the following code for modules with no source files
        if not self.SourceFileList:
            return

        # Skip the following code for modules without any binary files
        if self.BinaryFileList:
            return

        ### TODO: How to handles mixed source and binary modules

        # Find all DynamicEx and PatchableInModule PCDs used by this module and dependent libraries
        # Also find all packages that the DynamicEx PCDs depend on
        Pcds = []
        PatchablePcds = []
        Packages = []
        PcdCheckList = []
        PcdTokenSpaceList = []
        for Pcd in self.ModulePcdList + self.LibraryPcdList:
            if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
                PatchablePcds.append(Pcd)
                PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, TAB_PCDS_PATCHABLE_IN_MODULE))
            elif Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
                if Pcd not in Pcds:
                    Pcds.append(Pcd)
                    PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, TAB_PCDS_DYNAMIC_EX))
                    PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, TAB_PCDS_DYNAMIC))
                    PcdTokenSpaceList.append(Pcd.TokenSpaceGuidCName)
        GuidList = OrderedDict(self.GuidList)
        for TokenSpace in self.GetGuidsUsedByPcd:
            # If token space is not referred by patch PCD or Ex PCD, remove the GUID from GUID list
            # The GUIDs in GUIDs section should really be the GUIDs in source INF or referred by Ex an patch PCDs
            if TokenSpace not in PcdTokenSpaceList and TokenSpace in GuidList:
                GuidList.pop(TokenSpace)
        CheckList = (GuidList, self.PpiList, self.ProtocolList, PcdCheckList)
        for Package in self.DerivedPackageList:
            if Package in Packages:
                continue
            BeChecked = (Package.Guids, Package.Ppis, Package.Protocols, Package.Pcds)
            Found = False
            for Index in range(len(BeChecked)):
                for Item in CheckList[Index]:
                    if Item in BeChecked[Index]:
                        Packages.append(Package)
                        Found = True
                        break
                if Found:
                    break

        VfrPcds = self._GetPcdsMaybeUsedByVfr()
        for Pkg in self.PlatformInfo.PackageList:
            if Pkg in Packages:
                continue
            for VfrPcd in VfrPcds:
                if ((VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, TAB_PCDS_DYNAMIC_EX) in Pkg.Pcds or
                    (VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, TAB_PCDS_DYNAMIC) in Pkg.Pcds):
                    Packages.append(Pkg)
                    break

        ModuleType = SUP_MODULE_DXE_DRIVER if self.ModuleType == SUP_MODULE_UEFI_DRIVER and self.DepexGenerated else self.ModuleType
        DriverType = self.PcdIsDriver if self.PcdIsDriver else ''
        Guid = self.Guid
        MDefs = self.Module.Defines

        AsBuiltInfDict = {
          'module_name'                       : self.Name,
          'module_guid'                       : Guid,
          'module_module_type'                : ModuleType,
          'module_version_string'             : [MDefs['VERSION_STRING']] if 'VERSION_STRING' in MDefs else [],
          'pcd_is_driver_string'              : [],
          'module_uefi_specification_version' : [],
          'module_pi_specification_version'   : [],
          'module_entry_point'                : self.Module.ModuleEntryPointList,
          'module_unload_image'               : self.Module.ModuleUnloadImageList,
          'module_constructor'                : self.Module.ConstructorList,
          'module_destructor'                 : self.Module.DestructorList,
          'module_shadow'                     : [MDefs['SHADOW']] if 'SHADOW' in MDefs else [],
          'module_pci_vendor_id'              : [MDefs['PCI_VENDOR_ID']] if 'PCI_VENDOR_ID' in MDefs else [],
          'module_pci_device_id'              : [MDefs['PCI_DEVICE_ID']] if 'PCI_DEVICE_ID' in MDefs else [],
          'module_pci_class_code'             : [MDefs['PCI_CLASS_CODE']] if 'PCI_CLASS_CODE' in MDefs else [],
          'module_pci_revision'               : [MDefs['PCI_REVISION']] if 'PCI_REVISION' in MDefs else [],
          'module_build_number'               : [MDefs['BUILD_NUMBER']] if 'BUILD_NUMBER' in MDefs else [],
          'module_spec'                       : [MDefs['SPEC']] if 'SPEC' in MDefs else [],
          'module_uefi_hii_resource_section'  : [MDefs['UEFI_HII_RESOURCE_SECTION']] if 'UEFI_HII_RESOURCE_SECTION' in MDefs else [],
          'module_uni_file'                   : [MDefs['MODULE_UNI_FILE']] if 'MODULE_UNI_FILE' in MDefs else [],
          'module_arch'                       : self.Arch,
          'package_item'                      : [Package.MetaFile.File.replace('\\', '/') for Package in Packages],
          'binary_item'                       : [],
          'patchablepcd_item'                 : [],
          'pcd_item'                          : [],
          'protocol_item'                     : [],
          'ppi_item'                          : [],
          'guid_item'                         : [],
          'flags_item'                        : [],
          'libraryclasses_item'               : []
        }

        if 'MODULE_UNI_FILE' in MDefs:
            UNIFile = os.path.join(self.MetaFile.Dir, MDefs['MODULE_UNI_FILE'])
            if os.path.isfile(UNIFile):
                shutil.copy2(UNIFile, self.OutputDir)

        if self.AutoGenVersion > int(gInfSpecVersion, 0):
            AsBuiltInfDict['module_inf_version'] = '0x%08x' % self.AutoGenVersion
        else:
            AsBuiltInfDict['module_inf_version'] = gInfSpecVersion

        if DriverType:
            AsBuiltInfDict['pcd_is_driver_string'].append(DriverType)

        if 'UEFI_SPECIFICATION_VERSION' in self.Specification:
            AsBuiltInfDict['module_uefi_specification_version'].append(self.Specification['UEFI_SPECIFICATION_VERSION'])
        if 'PI_SPECIFICATION_VERSION' in self.Specification:
            AsBuiltInfDict['module_pi_specification_version'].append(self.Specification['PI_SPECIFICATION_VERSION'])

        OutputDir = self.OutputDir.replace('\\', '/').strip('/')
        DebugDir = self.DebugDir.replace('\\', '/').strip('/')
        for Item in self.CodaTargetList:
            File = Item.Target.Path.replace('\\', '/').strip('/').replace(DebugDir, '').replace(OutputDir, '').strip('/')
            if os.path.isabs(File):
                File = File.replace('\\', '/').strip('/').replace(OutputDir, '').strip('/')
            if Item.Target.Ext.lower() == '.aml':
                AsBuiltInfDict['binary_item'].append('ASL|' + File)
            elif Item.Target.Ext.lower() == '.acpi':
                AsBuiltInfDict['binary_item'].append('ACPI|' + File)
            elif Item.Target.Ext.lower() == '.efi':
                AsBuiltInfDict['binary_item'].append('PE32|' + self.Name + '.efi')
            else:
                AsBuiltInfDict['binary_item'].append('BIN|' + File)
        if not self.DepexGenerated:
            DepexFile = os.path.join(self.OutputDir, self.Name + '.depex')
            if os.path.exists(DepexFile):
                self.DepexGenerated = True
        if self.DepexGenerated:
            if self.ModuleType in [SUP_MODULE_PEIM]:
                AsBuiltInfDict['binary_item'].append('PEI_DEPEX|' + self.Name + '.depex')
            elif self.ModuleType in [SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_UEFI_DRIVER]:
                AsBuiltInfDict['binary_item'].append('DXE_DEPEX|' + self.Name + '.depex')
            elif self.ModuleType in [SUP_MODULE_DXE_SMM_DRIVER]:
                AsBuiltInfDict['binary_item'].append('SMM_DEPEX|' + self.Name + '.depex')

        Bin = self._GenOffsetBin()
        if Bin:
            AsBuiltInfDict['binary_item'].append('BIN|%s' % Bin)

        for Root, Dirs, Files in os.walk(OutputDir):
            for File in Files:
                if File.lower().endswith('.pdb'):
                    AsBuiltInfDict['binary_item'].append('DISPOSABLE|' + File)
        HeaderComments = self.Module.HeaderComments
        StartPos = 0
        for Index in range(len(HeaderComments)):
            if HeaderComments[Index].find('@BinaryHeader') != -1:
                HeaderComments[Index] = HeaderComments[Index].replace('@BinaryHeader', '@file')
                StartPos = Index
                break
        AsBuiltInfDict['header_comments'] = '\n'.join(HeaderComments[StartPos:]).replace(':#', '://')
        AsBuiltInfDict['tail_comments'] = '\n'.join(self.Module.TailComments)

        GenList = [
            (self.ProtocolList, self._ProtocolComments, 'protocol_item'),
            (self.PpiList, self._PpiComments, 'ppi_item'),
            (GuidList, self._GuidComments, 'guid_item')
        ]
        for Item in GenList:
            for CName in Item[0]:
                Comments = '\n  '.join(Item[1][CName]) if CName in Item[1] else ''
                Entry = Comments + '\n  ' + CName if Comments else CName
                AsBuiltInfDict[Item[2]].append(Entry)
        PatchList = parsePcdInfoFromMapFile(
                            os.path.join(self.OutputDir, self.Name + '.map'),
                            os.path.join(self.OutputDir, self.Name + '.efi')
                        )
        if PatchList:
            for Pcd in PatchablePcds:
                TokenCName = Pcd.TokenCName
                for PcdItem in GlobalData.MixedPcd:
                    if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
                        TokenCName = PcdItem[0]
                        break
                for PatchPcd in PatchList:
                    if TokenCName == PatchPcd[0]:
                        break
                else:
                    continue
                PcdValue = ''
                if Pcd.DatumType == 'BOOLEAN':
                    BoolValue = Pcd.DefaultValue.upper()
                    if BoolValue == 'TRUE':
                        Pcd.DefaultValue = '1'
                    elif BoolValue == 'FALSE':
                        Pcd.DefaultValue = '0'

                if Pcd.DatumType in TAB_PCD_NUMERIC_TYPES:
                    HexFormat = '0x%02x'
                    if Pcd.DatumType == TAB_UINT16:
                        HexFormat = '0x%04x'
                    elif Pcd.DatumType == TAB_UINT32:
                        HexFormat = '0x%08x'
                    elif Pcd.DatumType == TAB_UINT64:
                        HexFormat = '0x%016x'
                    PcdValue = HexFormat % int(Pcd.DefaultValue, 0)
                else:
                    if Pcd.MaxDatumSize is None or Pcd.MaxDatumSize == '':
                        EdkLogger.error("build", AUTOGEN_ERROR,
                                        "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName)
                                        )
                    ArraySize = int(Pcd.MaxDatumSize, 0)
                    PcdValue = Pcd.DefaultValue
                    if PcdValue[0] != '{':
                        Unicode = False
                        if PcdValue[0] == 'L':
                            Unicode = True
                        PcdValue = PcdValue.lstrip('L')
                        PcdValue = eval(PcdValue)
                        NewValue = '{'
                        for Index in range(0, len(PcdValue)):
                            if Unicode:
                                CharVal = ord(PcdValue[Index])
                                NewValue = NewValue + '0x%02x' % (CharVal & 0x00FF) + ', ' \
                                        + '0x%02x' % (CharVal >> 8) + ', '
                            else:
                                NewValue = NewValue + '0x%02x' % (ord(PcdValue[Index]) % 0x100) + ', '
                        Padding = '0x00, '
                        if Unicode:
                            Padding = Padding * 2
                            ArraySize = ArraySize // 2
                        if ArraySize < (len(PcdValue) + 1):
                            if Pcd.MaxSizeUserSet:
                                EdkLogger.error("build", AUTOGEN_ERROR,
                                            "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName)
                                            )
                            else:
                                ArraySize = len(PcdValue) + 1
                        if ArraySize > len(PcdValue) + 1:
                            NewValue = NewValue + Padding * (ArraySize - len(PcdValue) - 1)
                        PcdValue = NewValue + Padding.strip().rstrip(',') + '}'
                    elif len(PcdValue.split(',')) <= ArraySize:
                        PcdValue = PcdValue.rstrip('}') + ', 0x00' * (ArraySize - len(PcdValue.split(',')))
                        PcdValue += '}'
                    else:
                        if Pcd.MaxSizeUserSet:
                            EdkLogger.error("build", AUTOGEN_ERROR,
                                        "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName)
                                        )
                        else:
                            ArraySize = len(PcdValue) + 1
                PcdItem = '%s.%s|%s|0x%X' % \
                    (Pcd.TokenSpaceGuidCName, TokenCName, PcdValue, PatchPcd[1])
                PcdComments = ''
                if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:
                    PcdComments = '\n  '.join(self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName])
                if PcdComments:
                    PcdItem = PcdComments + '\n  ' + PcdItem
                AsBuiltInfDict['patchablepcd_item'].append(PcdItem)

        for Pcd in Pcds + VfrPcds:
            PcdCommentList = []
            HiiInfo = ''
            TokenCName = Pcd.TokenCName
            for PcdItem in GlobalData.MixedPcd:
                if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
                    TokenCName = PcdItem[0]
                    break
            if Pcd.Type == TAB_PCDS_DYNAMIC_EX_HII:
                for SkuName in Pcd.SkuInfoList:
                    SkuInfo = Pcd.SkuInfoList[SkuName]
                    HiiInfo = '## %s|%s|%s' % (SkuInfo.VariableName, SkuInfo.VariableGuid, SkuInfo.VariableOffset)
                    break
            if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:
                PcdCommentList = self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName][:]
            if HiiInfo:
                UsageIndex = -1
                UsageStr = ''
                for Index, Comment in enumerate(PcdCommentList):
                    for Usage in UsageList:
                        if Comment.find(Usage) != -1:
                            UsageStr = Usage
                            UsageIndex = Index
                            break
                if UsageIndex != -1:
                    PcdCommentList[UsageIndex] = '## %s %s %s' % (UsageStr, HiiInfo, PcdCommentList[UsageIndex].replace(UsageStr, ''))
                else:
                    PcdCommentList.append('## UNDEFINED ' + HiiInfo)
            PcdComments = '\n  '.join(PcdCommentList)
            PcdEntry = Pcd.TokenSpaceGuidCName + '.' + TokenCName
            if PcdComments:
                PcdEntry = PcdComments + '\n  ' + PcdEntry
            AsBuiltInfDict['pcd_item'].append(PcdEntry)
        for Item in self.BuildOption:
            if 'FLAGS' in self.BuildOption[Item]:
                AsBuiltInfDict['flags_item'].append('%s:%s_%s_%s_%s_FLAGS = %s' % (self.ToolChainFamily, self.BuildTarget, self.ToolChain, self.Arch, Item, self.BuildOption[Item]['FLAGS'].strip()))

        # Generated LibraryClasses section in comments.
        for Library in self.LibraryAutoGenList:
            AsBuiltInfDict['libraryclasses_item'].append(Library.MetaFile.File.replace('\\', '/'))

        # Generated UserExtensions TianoCore section.
        # All tianocore user extensions are copied.
        UserExtStr = ''
        for TianoCore in self._GetTianoCoreUserExtensionList():
            UserExtStr += '\n'.join(TianoCore)
            ExtensionFile = os.path.join(self.MetaFile.Dir, TianoCore[1])
            if os.path.isfile(ExtensionFile):
                shutil.copy2(ExtensionFile, self.OutputDir)
        AsBuiltInfDict['userextension_tianocore_item'] = UserExtStr

        # Generated depex expression section in comments.
        DepexExpression = self._GetDepexExpresionString()
        AsBuiltInfDict['depexsection_item'] = DepexExpression if DepexExpression else ''

        AsBuiltInf = TemplateString()
        AsBuiltInf.Append(gAsBuiltInfHeaderString.Replace(AsBuiltInfDict))

        SaveFileOnChange(os.path.join(self.OutputDir, self.Name + '.inf'), str(AsBuiltInf), False)

        self.IsAsBuiltInfCreated = True

    def CacheCopyFile(self, DestDir, SourceDir, File):
        if os.path.isdir(File):
            return

        sub_dir = os.path.relpath(File, SourceDir)
        destination_file = os.path.join(DestDir, sub_dir)
        destination_dir = os.path.dirname(destination_file)
        CreateDirectory(destination_dir)
        try:
            CopyFileOnChange(File, destination_dir)
        except:
            EdkLogger.quiet("[cache warning]: fail to copy file:%s to folder:%s" % (File, destination_dir))
            return

    def CopyModuleToCache(self):
        # Find the MakeHashStr and PreMakeHashStr from latest MakeHashFileList
        # and PreMakeHashFileList files
        MakeHashStr = None
        PreMakeHashStr = None
        MakeTimeStamp = 0
        PreMakeTimeStamp = 0
        Files = [f for f in os.listdir(LongFilePath(self.BuildDir)) if path.isfile(LongFilePath(path.join(self.BuildDir, f)))]
        for File in Files:
            if ".MakeHashFileList." in File:
                #find lastest file through time stamp
                FileTimeStamp = os.stat(LongFilePath(path.join(self.BuildDir, File)))[8]
                if FileTimeStamp > MakeTimeStamp:
                    MakeTimeStamp = FileTimeStamp
                    MakeHashStr = File.split('.')[-1]
                    if len(MakeHashStr) != 32:
                        EdkLogger.quiet("[cache error]: wrong MakeHashFileList file:%s" % (File))
            if ".PreMakeHashFileList." in File:
                FileTimeStamp = os.stat(LongFilePath(path.join(self.BuildDir, File)))[8]
                if FileTimeStamp > PreMakeTimeStamp:
                    PreMakeTimeStamp = FileTimeStamp
                    PreMakeHashStr = File.split('.')[-1]
                    if len(PreMakeHashStr) != 32:
                        EdkLogger.quiet("[cache error]: wrong PreMakeHashFileList file:%s" % (File))

        if not MakeHashStr:
            EdkLogger.quiet("[cache error]: No MakeHashFileList file for module:%s[%s]" % (self.MetaFile.Path, self.Arch))
            return
        if not PreMakeHashStr:
            EdkLogger.quiet("[cache error]: No PreMakeHashFileList file for module:%s[%s]" % (self.MetaFile.Path, self.Arch))
            return

        # Create Cache destination dirs
        FileDir = path.join(GlobalData.gBinCacheDest, self.PlatformInfo.OutputDir, self.BuildTarget + "_" + self.ToolChain, self.Arch, self.SourceDir, self.MetaFile.BaseName)
        FfsDir = path.join(GlobalData.gBinCacheDest, self.PlatformInfo.OutputDir, self.BuildTarget + "_" + self.ToolChain, TAB_FV_DIRECTORY, "Ffs", self.Guid + self.Name)
        CacheFileDir = path.join(FileDir, MakeHashStr)
        CacheFfsDir = path.join(FfsDir, MakeHashStr)
        CreateDirectory (CacheFileDir)
        CreateDirectory (CacheFfsDir)

        # Create ModuleHashPair file to support multiple version cache together
        ModuleHashPair = path.join(FileDir, self.Name + ".ModuleHashPair")
        ModuleHashPairList = [] # tuple list: [tuple(PreMakefileHash, MakeHash)]
        if os.path.exists(ModuleHashPair):
            with open(ModuleHashPair, 'r') as f:
                ModuleHashPairList = json.load(f)
        if not (PreMakeHashStr, MakeHashStr) in set(map(tuple, ModuleHashPairList)):
            ModuleHashPairList.insert(0, (PreMakeHashStr, MakeHashStr))
            with open(ModuleHashPair, 'w') as f:
                json.dump(ModuleHashPairList, f, indent=2)

        # Copy files to Cache destination dirs
        if not self.OutputFile:
            Ma = self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]
            self.OutputFile = Ma.Binaries
        for File in self.OutputFile:
            if File.startswith(os.path.abspath(self.FfsOutputDir)+os.sep):
                self.CacheCopyFile(CacheFfsDir, self.FfsOutputDir, File)
            else:
                if  self.Name + ".autogen.hash." in File or \
                    self.Name + ".autogen.hashchain." in File or \
                    self.Name + ".hash." in File or \
                    self.Name + ".hashchain." in File or \
                    self.Name + ".PreMakeHashFileList." in File or \
                    self.Name + ".MakeHashFileList." in File:
                    self.CacheCopyFile(FileDir, self.BuildDir, File)
                else:
                    self.CacheCopyFile(CacheFileDir, self.BuildDir, File)
    ## Create makefile for the module and its dependent libraries
    #
    #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of
    #                                       dependent libraries will be created
    #
    @cached_class_function
    def CreateMakeFile(self, CreateLibraryMakeFile=True, GenFfsList = []):

        # nest this function inside it's only caller.
        def CreateTimeStamp():
            FileSet = {self.MetaFile.Path}

            for SourceFile in self.Module.Sources:
                FileSet.add (SourceFile.Path)

            for Lib in self.DependentLibraryList:
                FileSet.add (Lib.MetaFile.Path)

            for f in self.AutoGenDepSet:
                FileSet.add (f.Path)

            if os.path.exists (self.TimeStampPath):
                os.remove (self.TimeStampPath)

            SaveFileOnChange(self.TimeStampPath, "\n".join(FileSet), False)

        # Ignore generating makefile when it is a binary module
        if self.IsBinaryModule:
            return

        self.GenFfsList = GenFfsList

        if not self.IsLibrary and CreateLibraryMakeFile:
            for LibraryAutoGen in self.LibraryAutoGenList:
                LibraryAutoGen.CreateMakeFile()

        # CanSkip uses timestamps to determine build skipping
        if self.CanSkip():
            return

        if len(self.CustomMakefile) == 0:
            Makefile = GenMake.ModuleMakefile(self)
        else:
            Makefile = GenMake.CustomMakefile(self)
        if Makefile.Generate():
            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for module %s [%s]" %
                            (self.Name, self.Arch))
        else:
            EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %
                            (self.Name, self.Arch))

        CreateTimeStamp()

        MakefileType = Makefile._FileType
        MakefileName = Makefile._FILE_NAME_[MakefileType]
        MakefilePath = os.path.join(self.MakeFileDir, MakefileName)
        FilePath = path.join(self.BuildDir, self.Name + ".makefile")
        SaveFileOnChange(FilePath, MakefilePath, False)

    def CopyBinaryFiles(self):
        for File in self.Module.Binaries:
            SrcPath = File.Path
            DstPath = os.path.join(self.OutputDir, os.path.basename(SrcPath))
            CopyLongFilePath(SrcPath, DstPath)
    ## Create autogen code for the module and its dependent libraries
    #
    #   @param      CreateLibraryCodeFile   Flag indicating if or not the code of
    #                                       dependent libraries will be created
    #
    def CreateCodeFile(self, CreateLibraryCodeFile=True):

        if self.IsCodeFileCreated:
            return

        # Need to generate PcdDatabase even PcdDriver is binarymodule
        if self.IsBinaryModule and self.PcdIsDriver != '':
            CreatePcdDatabaseCode(self, TemplateString(), TemplateString())
            return
        if self.IsBinaryModule:
            if self.IsLibrary:
                self.CopyBinaryFiles()
            return

        if not self.IsLibrary and CreateLibraryCodeFile:
            for LibraryAutoGen in self.LibraryAutoGenList:
                LibraryAutoGen.CreateCodeFile()

        self.LibraryAutoGenList
        AutoGenList = []
        IgoredAutoGenList = []

        for File in self.AutoGenFileList:
            if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary):
                AutoGenList.append(str(File))
            else:
                IgoredAutoGenList.append(str(File))


        for ModuleType in self.DepexList:
            # Ignore empty [depex] section or [depex] section for SUP_MODULE_USER_DEFINED module
            if len(self.DepexList[ModuleType]) == 0 or ModuleType == SUP_MODULE_USER_DEFINED or ModuleType == SUP_MODULE_HOST_APPLICATION:
                continue

            Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True)
            DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}

            if len(Dpx.PostfixNotation) != 0:
                self.DepexGenerated = True

            if Dpx.Generate(path.join(self.OutputDir, DpxFile)):
                AutoGenList.append(str(DpxFile))
            else:
                IgoredAutoGenList.append(str(DpxFile))

        if IgoredAutoGenList == []:
            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] files for module %s [%s]" %
                            (" ".join(AutoGenList), self.Name, self.Arch))
        elif AutoGenList == []:
            EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of [%s] files for module %s [%s]" %
                            (" ".join(IgoredAutoGenList), self.Name, self.Arch))
        else:
            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] (skipped %s) files for module %s [%s]" %
                            (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))

        self.IsCodeFileCreated = True

        return AutoGenList

    ## Summarize the ModuleAutoGen objects of all libraries used by this module
    @cached_property
    def LibraryAutoGenList(self):
        RetVal = []
        for Library in self.DependentLibraryList:
            La = ModuleAutoGen(
                        self.Workspace,
                        Library.MetaFile,
                        self.BuildTarget,
                        self.ToolChain,
                        self.Arch,
                        self.PlatformInfo.MetaFile,
                        self.DataPipe
                        )
            La.IsLibrary = True
            if La not in RetVal:
                RetVal.append(La)
                for Lib in La.CodaTargetList:
                    self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)
        return RetVal

    def GenCMakeHash(self):
        # GenCMakeHash can only be called in --binary-destination
        # Never called in multiprocessing and always directly save result in main process,
        # so no need remote dict to share the gCMakeHashFile result with main process

        DependencyFileSet = set()
        # Add AutoGen files
        if self.AutoGenFileList:
            for File in set(self.AutoGenFileList):
                DependencyFileSet.add(File)

        # Add Makefile
        abspath = path.join(self.BuildDir, self.Name + ".makefile")
        try:
            with open(LongFilePath(abspath),"r") as fd:
                lines = fd.readlines()
        except Exception as e:
            EdkLogger.error("build",FILE_NOT_FOUND, "%s doesn't exist" % abspath, ExtraData=str(e), RaiseError=False)
        if lines:
            DependencyFileSet.update(lines)

        # Caculate all above dependency files hash
        # Initialze hash object
        FileList = []
        m = hashlib.md5()
        for File in sorted(DependencyFileSet, key=lambda x: str(x)):
            if not path.exists(LongFilePath(str(File))):
                EdkLogger.quiet("[cache warning]: header file %s is missing for module: %s[%s]" % (File, self.MetaFile.Path, self.Arch))
                continue
            with open(LongFilePath(str(File)), 'rb') as f:
                Content = f.read()
            m.update(Content)
            FileList.append((str(File), hashlib.md5(Content).hexdigest()))

        HashChainFile = path.join(self.BuildDir, self.Name + ".autogen.hashchain." + m.hexdigest())
        GlobalData.gCMakeHashFile[(self.MetaFile.Path, self.Arch)] = HashChainFile
        try:
            with open(LongFilePath(HashChainFile), 'w') as f:
                json.dump(FileList, f, indent=2)
        except:
            EdkLogger.quiet("[cache warning]: fail to save hashchain file:%s" % HashChainFile)
            return False

    def GenModuleHash(self):
        # GenModuleHash only called after autogen phase
        # Never called in multiprocessing and always directly save result in main process,
        # so no need remote dict to share the gModuleHashFile result with main process
        #
        # GenPreMakefileHashList consume no dict.
        # GenPreMakefileHashList produce local gModuleHashFile dict.

        DependencyFileSet = set()
        # Add Module Meta file
        DependencyFileSet.add(self.MetaFile.Path)

        # Add Module's source files
        if self.SourceFileList:
            for File in set(self.SourceFileList):
                DependencyFileSet.add(File.Path)

        # Add modules's include header files
        # Directly use the deps.txt file in the module BuildDir
        abspath = path.join(self.BuildDir, "deps.txt")
        rt = None
        try:
            with open(LongFilePath(abspath),"r") as fd:
                lines = fd.readlines()
                if lines:
                    rt = set([item.lstrip().strip("\n") for item in lines if item.strip("\n").endswith(".h")])
        except Exception as e:
            EdkLogger.error("build",FILE_NOT_FOUND, "%s doesn't exist" % abspath, ExtraData=str(e), RaiseError=False)

        if rt:
            DependencyFileSet.update(rt)


        # Caculate all above dependency files hash
        # Initialze hash object
        FileList = []
        m = hashlib.md5()
        BuildDirStr = path.abspath(self.BuildDir).lower()
        for File in sorted(DependencyFileSet, key=lambda x: str(x)):
            # Skip the AutoGen files in BuildDir which already been
            # included in .autogen.hash. file
            if BuildDirStr in path.abspath(File).lower():
                continue
            if not path.exists(LongFilePath(File)):
                EdkLogger.quiet("[cache warning]: header file %s is missing for module: %s[%s]" % (File, self.MetaFile.Path, self.Arch))
                continue
            with open(LongFilePath(File), 'rb') as f:
                Content = f.read()
            m.update(Content)
            FileList.append((File, hashlib.md5(Content).hexdigest()))

        HashChainFile = path.join(self.BuildDir, self.Name + ".hashchain." + m.hexdigest())
        GlobalData.gModuleHashFile[(self.MetaFile.Path, self.Arch)] = HashChainFile
        try:
            with open(LongFilePath(HashChainFile), 'w') as f:
                json.dump(FileList, f, indent=2)
        except:
            EdkLogger.quiet("[cache warning]: fail to save hashchain file:%s" % HashChainFile)
            return False

    def GenPreMakefileHashList(self):
        # GenPreMakefileHashList consume below dicts:
        #     gPlatformHashFile
        #     gPackageHashFile
        #     gModuleHashFile
        # GenPreMakefileHashList produce no dict.
        # gModuleHashFile items might be produced in multiprocessing, so
        # need check gModuleHashFile remote dict

        # skip binary module
        if self.IsBinaryModule:
            return

        FileList = []
        m = hashlib.md5()
        # Add Platform level hash
        HashFile = GlobalData.gPlatformHashFile
        if path.exists(LongFilePath(HashFile)):
            FileList.append(HashFile)
            m.update(HashFile.encode('utf-8'))
        else:
            EdkLogger.quiet("[cache warning]: No Platform HashFile: %s" % HashFile)

        # Add Package level hash
        if self.DependentPackageList:
            for Pkg in sorted(self.DependentPackageList, key=lambda x: x.PackageName):
                if not (Pkg.PackageName, Pkg.Arch) in GlobalData.gPackageHashFile:
                    EdkLogger.quiet("[cache warning]:No Package %s for module %s[%s]" % (Pkg.PackageName, self.MetaFile.Path, self.Arch))
                    continue
                HashFile = GlobalData.gPackageHashFile[(Pkg.PackageName, Pkg.Arch)]
                if path.exists(LongFilePath(HashFile)):
                    FileList.append(HashFile)
                    m.update(HashFile.encode('utf-8'))
                else:
                    EdkLogger.quiet("[cache warning]:No Package HashFile: %s" % HashFile)

        # Add Module self
        # GenPreMakefileHashList needed in both --binary-destination
        # and --hash. And --hash might save ModuleHashFile in remote dict
        # during multiprocessing.
        if (self.MetaFile.Path, self.Arch) in GlobalData.gModuleHashFile:
            HashFile = GlobalData.gModuleHashFile[(self.MetaFile.Path, self.Arch)]
        else:
            EdkLogger.quiet("[cache error]:No ModuleHashFile for module: %s[%s]" % (self.MetaFile.Path, self.Arch))
        if path.exists(LongFilePath(HashFile)):
            FileList.append(HashFile)
            m.update(HashFile.encode('utf-8'))
        else:
            EdkLogger.quiet("[cache warning]:No Module HashFile: %s" % HashFile)

        # Add Library hash
        if self.LibraryAutoGenList:
            for Lib in sorted(self.LibraryAutoGenList, key=lambda x: x.MetaFile.Path):

                if (Lib.MetaFile.Path, Lib.Arch) in GlobalData.gModuleHashFile:
                    HashFile = GlobalData.gModuleHashFile[(Lib.MetaFile.Path, Lib.Arch)]
                else:
                    EdkLogger.quiet("[cache error]:No ModuleHashFile for lib: %s[%s]" % (Lib.MetaFile.Path, Lib.Arch))
                if path.exists(LongFilePath(HashFile)):
                    FileList.append(HashFile)
                    m.update(HashFile.encode('utf-8'))
                else:
                    EdkLogger.quiet("[cache warning]:No Lib HashFile: %s" % HashFile)

        # Save PreMakeHashFileList
        FilePath = path.join(self.BuildDir, self.Name + ".PreMakeHashFileList." + m.hexdigest())
        try:
            with open(LongFilePath(FilePath), 'w') as f:
                json.dump(FileList, f, indent=0)
        except:
            EdkLogger.quiet("[cache warning]: fail to save PreMake HashFileList: %s" % FilePath)

    def GenMakefileHashList(self):
        # GenMakefileHashList only need in --binary-destination which will
        # everything in local dict. So don't need check remote dict.

        # skip binary module
        if self.IsBinaryModule:
            return

        FileList = []
        m = hashlib.md5()
        # Add AutoGen hash
        HashFile = GlobalData.gCMakeHashFile[(self.MetaFile.Path, self.Arch)]
        if path.exists(LongFilePath(HashFile)):
            FileList.append(HashFile)
            m.update(HashFile.encode('utf-8'))
        else:
            EdkLogger.quiet("[cache warning]:No AutoGen HashFile: %s" % HashFile)

        # Add Module self
        if (self.MetaFile.Path, self.Arch) in GlobalData.gModuleHashFile:
            HashFile = GlobalData.gModuleHashFile[(self.MetaFile.Path, self.Arch)]
        else:
            EdkLogger.quiet("[cache error]:No ModuleHashFile for module: %s[%s]" % (self.MetaFile.Path, self.Arch))
        if path.exists(LongFilePath(HashFile)):
            FileList.append(HashFile)
            m.update(HashFile.encode('utf-8'))
        else:
            EdkLogger.quiet("[cache warning]:No Module HashFile: %s" % HashFile)

        # Add Library hash
        if self.LibraryAutoGenList:
            for Lib in sorted(self.LibraryAutoGenList, key=lambda x: x.MetaFile.Path):
                if (Lib.MetaFile.Path, Lib.Arch) in GlobalData.gModuleHashFile:
                    HashFile = GlobalData.gModuleHashFile[(Lib.MetaFile.Path, Lib.Arch)]
                else:
                    EdkLogger.quiet("[cache error]:No ModuleHashFile for lib: %s[%s]" % (Lib.MetaFile.Path, Lib.Arch))
                if path.exists(LongFilePath(HashFile)):
                    FileList.append(HashFile)
                    m.update(HashFile.encode('utf-8'))
                else:
                    EdkLogger.quiet("[cache warning]:No Lib HashFile: %s" % HashFile)

        # Save MakeHashFileList
        FilePath = path.join(self.BuildDir, self.Name + ".MakeHashFileList." + m.hexdigest())
        try:
            with open(LongFilePath(FilePath), 'w') as f:
                json.dump(FileList, f, indent=0)
        except:
            EdkLogger.quiet("[cache warning]: fail to save Make HashFileList: %s" % FilePath)

    def CheckHashChainFile(self, HashChainFile):
        # Assume the HashChainFile basename format is the 'x.hashchain.16BytesHexStr'
        # The x is module name and the 16BytesHexStr is md5 hexdigest of
        # all hashchain files content
        HashStr = HashChainFile.split('.')[-1]
        if len(HashStr) != 32:
            EdkLogger.quiet("[cache error]: wrong format HashChainFile:%s" % (File))
            return False

        try:
            with open(LongFilePath(HashChainFile), 'r') as f:
                HashChainList = json.load(f)
        except:
            EdkLogger.quiet("[cache error]: fail to load HashChainFile: %s" % HashChainFile)
            return False

        # Print the different file info
        # print(HashChainFile)
        for idx, (SrcFile, SrcHash) in enumerate (HashChainList):
            if SrcFile in GlobalData.gFileHashDict:
                DestHash = GlobalData.gFileHashDict[SrcFile]
            else:
                try:
                    with open(LongFilePath(SrcFile), 'rb') as f:
                        Content = f.read()
                        DestHash = hashlib.md5(Content).hexdigest()
                        GlobalData.gFileHashDict[SrcFile] = DestHash
                except IOError as X:
                    # cache miss if SrcFile is removed in new version code
                    GlobalData.gFileHashDict[SrcFile] = 0
                    EdkLogger.quiet("[cache insight]: first cache miss file in %s is %s" % (HashChainFile, SrcFile))
                    return False
            if SrcHash != DestHash:
                EdkLogger.quiet("[cache insight]: first cache miss file in %s is %s" % (HashChainFile, SrcFile))
                return False

        return True

    ## Decide whether we can skip the left autogen and make process
    def CanSkipbyMakeCache(self):
        # For --binary-source only
        # CanSkipbyMakeCache consume below dicts:
        #     gModuleMakeCacheStatus
        #     gHashChainStatus
        # GenPreMakefileHashList produce gModuleMakeCacheStatus, gModuleHashFile dict.
        # all these dicts might be produced in multiprocessing, so
        # need check these remote dict

        if not GlobalData.gBinCacheSource:
            return False

        if (self.MetaFile.Path, self.Arch) in GlobalData.gModuleMakeCacheStatus:
            return GlobalData.gModuleMakeCacheStatus[(self.MetaFile.Path, self.Arch)]

        # If Module is binary, which has special build rule, do not skip by cache.
        if self.IsBinaryModule:
            print("[cache miss]: MakeCache: Skip BinaryModule:", self.MetaFile.Path, self.Arch)
            GlobalData.gModuleMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = False
            return False

        # see .inc as binary file, do not skip by hash
        for f_ext in self.SourceFileList:
            if '.inc' in str(f_ext):
                print("[cache miss]: MakeCache: Skip '.inc' File:", self.MetaFile.Path, self.Arch)
                GlobalData.gModuleMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = False
                return False

        ModuleCacheDir = path.join(GlobalData.gBinCacheSource, self.PlatformInfo.OutputDir, self.BuildTarget + "_" + self.ToolChain, self.Arch, self.SourceDir, self.MetaFile.BaseName)
        FfsDir = path.join(GlobalData.gBinCacheSource, self.PlatformInfo.OutputDir, self.BuildTarget + "_" + self.ToolChain, TAB_FV_DIRECTORY, "Ffs", self.Guid + self.Name)

        ModuleHashPairList = [] # tuple list: [tuple(PreMakefileHash, MakeHash)]
        ModuleHashPair = path.join(ModuleCacheDir, self.Name + ".ModuleHashPair")
        try:
            with open(LongFilePath(ModuleHashPair), 'r') as f:
                ModuleHashPairList = json.load(f)
        except:
            # ModuleHashPair might not exist for new added module
            GlobalData.gModuleMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = False
            EdkLogger.quiet("[cache warning]: fail to load ModuleHashPair file: %s" % ModuleHashPair)
            print("[cache miss]: MakeCache:", self.MetaFile.Path, self.Arch)
            return False

        # Check the PreMakeHash in ModuleHashPairList one by one
        for idx, (PreMakefileHash, MakeHash) in enumerate (ModuleHashPairList):
            SourceHashDir = path.join(ModuleCacheDir, MakeHash)
            SourceFfsHashDir = path.join(FfsDir, MakeHash)
            PreMakeHashFileList_FilePah = path.join(ModuleCacheDir, self.Name + ".PreMakeHashFileList." + PreMakefileHash)
            MakeHashFileList_FilePah = path.join(ModuleCacheDir, self.Name + ".MakeHashFileList." + MakeHash)

            try:
                with open(LongFilePath(MakeHashFileList_FilePah), 'r') as f:
                    MakeHashFileList = json.load(f)
            except:
                EdkLogger.quiet("[cache error]: fail to load MakeHashFileList file: %s" % MakeHashFileList_FilePah)
                continue

            HashMiss = False
            for HashChainFile in MakeHashFileList:
                HashChainStatus = None
                if HashChainFile in GlobalData.gHashChainStatus:
                    HashChainStatus = GlobalData.gHashChainStatus[HashChainFile]
                if HashChainStatus == False:
                    HashMiss = True
                    break
                elif HashChainStatus == True:
                    continue
                # Convert to path start with cache source dir
                RelativePath = os.path.relpath(HashChainFile, self.WorkspaceDir)
                NewFilePath = os.path.join(GlobalData.gBinCacheSource, RelativePath)
                if self.CheckHashChainFile(NewFilePath):
                    GlobalData.gHashChainStatus[HashChainFile] = True
                    # Save the module self HashFile for GenPreMakefileHashList later usage
                    if self.Name + ".hashchain." in HashChainFile:
                        GlobalData.gModuleHashFile[(self.MetaFile.Path, self.Arch)] = HashChainFile
                else:
                    GlobalData.gHashChainStatus[HashChainFile] = False
                    HashMiss = True
                    break

            if HashMiss:
                continue

            # PreMakefile cache hit, restore the module build result
            for root, dir, files in os.walk(SourceHashDir):
                for f in files:
                    File = path.join(root, f)
                    self.CacheCopyFile(self.BuildDir, SourceHashDir, File)
            if os.path.exists(SourceFfsHashDir):
                for root, dir, files in os.walk(SourceFfsHashDir):
                    for f in files:
                        File = path.join(root, f)
                        self.CacheCopyFile(self.FfsOutputDir, SourceFfsHashDir, File)

            if self.Name == "PcdPeim" or self.Name == "PcdDxe":
                CreatePcdDatabaseCode(self, TemplateString(), TemplateString())

            print("[cache hit]: MakeCache:", self.MetaFile.Path, self.Arch)
            GlobalData.gModuleMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = True
            return True

        print("[cache miss]: MakeCache:", self.MetaFile.Path, self.Arch)
        GlobalData.gModuleMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = False
        return False

    ## Decide whether we can skip the left autogen and make process
    def CanSkipbyPreMakeCache(self):
        # CanSkipbyPreMakeCache consume below dicts:
        #     gModulePreMakeCacheStatus
        #     gHashChainStatus
        #     gModuleHashFile
        # GenPreMakefileHashList produce gModulePreMakeCacheStatus dict.
        # all these dicts might be produced in multiprocessing, so
        # need check these remote dicts

        if not GlobalData.gUseHashCache or GlobalData.gBinCacheDest:
            return False

        if (self.MetaFile.Path, self.Arch) in GlobalData.gModulePreMakeCacheStatus:
            return GlobalData.gModulePreMakeCacheStatus[(self.MetaFile.Path, self.Arch)]

        # If Module is binary, which has special build rule, do not skip by cache.
        if self.IsBinaryModule:
            print("[cache miss]: PreMakeCache: Skip BinaryModule:", self.MetaFile.Path, self.Arch)
            GlobalData.gModulePreMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = False
            return False

        # see .inc as binary file, do not skip by hash
        for f_ext in self.SourceFileList:
            if '.inc' in str(f_ext):
                print("[cache miss]: PreMakeCache: Skip '.inc' File:", self.MetaFile.Path, self.Arch)
                GlobalData.gModulePreMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = False
                return False

        # For --hash only in the incremental build
        if not GlobalData.gBinCacheSource:
            Files = [path.join(self.BuildDir, f) for f in os.listdir(self.BuildDir) if path.isfile(path.join(self.BuildDir, f))]
            PreMakeHashFileList_FilePah = None
            MakeTimeStamp = 0
            # Find latest PreMakeHashFileList file in self.BuildDir folder
            for File in Files:
                if ".PreMakeHashFileList." in File:
                    FileTimeStamp = os.stat(path.join(self.BuildDir, File))[8]
                    if FileTimeStamp > MakeTimeStamp:
                        MakeTimeStamp = FileTimeStamp
                        PreMakeHashFileList_FilePah = File
            if not PreMakeHashFileList_FilePah:
                GlobalData.gModulePreMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = False
                return False

            try:
                with open(LongFilePath(PreMakeHashFileList_FilePah), 'r') as f:
                    PreMakeHashFileList = json.load(f)
            except:
                EdkLogger.quiet("[cache error]: fail to load PreMakeHashFileList file: %s" % PreMakeHashFileList_FilePah)
                print("[cache miss]: PreMakeCache:", self.MetaFile.Path, self.Arch)
                GlobalData.gModulePreMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = False
                return False

            HashMiss = False
            for HashChainFile in PreMakeHashFileList:
                HashChainStatus = None
                if HashChainFile in GlobalData.gHashChainStatus:
                    HashChainStatus = GlobalData.gHashChainStatus[HashChainFile]
                if HashChainStatus == False:
                    HashMiss = True
                    break
                elif HashChainStatus == True:
                    continue
                if self.CheckHashChainFile(HashChainFile):
                    GlobalData.gHashChainStatus[HashChainFile] = True
                    # Save the module self HashFile for GenPreMakefileHashList later usage
                    if self.Name + ".hashchain." in HashChainFile:
                        GlobalData.gModuleHashFile[(self.MetaFile.Path, self.Arch)] = HashChainFile
                else:
                    GlobalData.gHashChainStatus[HashChainFile] = False
                    HashMiss = True
                    break

            if HashMiss:
                print("[cache miss]: PreMakeCache:", self.MetaFile.Path, self.Arch)
                GlobalData.gModulePreMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = False
                return False
            else:
                print("[cache hit]: PreMakeCache:", self.MetaFile.Path, self.Arch)
                GlobalData.gModulePreMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = True
                return True

        ModuleCacheDir = path.join(GlobalData.gBinCacheSource, self.PlatformInfo.OutputDir, self.BuildTarget + "_" + self.ToolChain, self.Arch, self.SourceDir, self.MetaFile.BaseName)
        FfsDir = path.join(GlobalData.gBinCacheSource, self.PlatformInfo.OutputDir, self.BuildTarget + "_" + self.ToolChain, TAB_FV_DIRECTORY, "Ffs", self.Guid + self.Name)

        ModuleHashPairList = [] # tuple list: [tuple(PreMakefileHash, MakeHash)]
        ModuleHashPair = path.join(ModuleCacheDir, self.Name + ".ModuleHashPair")
        try:
            with open(LongFilePath(ModuleHashPair), 'r') as f:
                ModuleHashPairList = json.load(f)
        except:
            # ModuleHashPair might not exist for new added module
            GlobalData.gModulePreMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = False
            EdkLogger.quiet("[cache warning]: fail to load ModuleHashPair file: %s" % ModuleHashPair)
            print("[cache miss]: PreMakeCache:", self.MetaFile.Path, self.Arch)
            return False

        # Check the PreMakeHash in ModuleHashPairList one by one
        for idx, (PreMakefileHash, MakeHash) in enumerate (ModuleHashPairList):
            SourceHashDir = path.join(ModuleCacheDir, MakeHash)
            SourceFfsHashDir = path.join(FfsDir, MakeHash)
            PreMakeHashFileList_FilePah = path.join(ModuleCacheDir, self.Name + ".PreMakeHashFileList." + PreMakefileHash)
            MakeHashFileList_FilePah = path.join(ModuleCacheDir, self.Name + ".MakeHashFileList." + MakeHash)

            try:
                with open(LongFilePath(PreMakeHashFileList_FilePah), 'r') as f:
                    PreMakeHashFileList = json.load(f)
            except:
                EdkLogger.quiet("[cache error]: fail to load PreMakeHashFileList file: %s" % PreMakeHashFileList_FilePah)
                continue

            HashMiss = False
            for HashChainFile in PreMakeHashFileList:
                HashChainStatus = None
                if HashChainFile in GlobalData.gHashChainStatus:
                    HashChainStatus = GlobalData.gHashChainStatus[HashChainFile]
                if HashChainStatus == False:
                    HashMiss = True
                    break
                elif HashChainStatus == True:
                    continue
                # Convert to path start with cache source dir
                RelativePath = os.path.relpath(HashChainFile, self.WorkspaceDir)
                NewFilePath = os.path.join(GlobalData.gBinCacheSource, RelativePath)
                if self.CheckHashChainFile(NewFilePath):
                    GlobalData.gHashChainStatus[HashChainFile] = True
                else:
                    GlobalData.gHashChainStatus[HashChainFile] = False
                    HashMiss = True
                    break

            if HashMiss:
                continue

            # PreMakefile cache hit, restore the module build result
            for root, dir, files in os.walk(SourceHashDir):
                for f in files:
                    File = path.join(root, f)
                    self.CacheCopyFile(self.BuildDir, SourceHashDir, File)
            if os.path.exists(SourceFfsHashDir):
                for root, dir, files in os.walk(SourceFfsHashDir):
                    for f in files:
                        File = path.join(root, f)
                        self.CacheCopyFile(self.FfsOutputDir, SourceFfsHashDir, File)

            if self.Name == "PcdPeim" or self.Name == "PcdDxe":
                CreatePcdDatabaseCode(self, TemplateString(), TemplateString())

            print("[cache hit]: PreMakeCache:", self.MetaFile.Path, self.Arch)
            GlobalData.gModulePreMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = True
            return True

        print("[cache miss]: PreMakeCache:", self.MetaFile.Path, self.Arch)
        GlobalData.gModulePreMakeCacheStatus[(self.MetaFile.Path, self.Arch)] = False
        return False

    ## Decide whether we can skip the Module build
    def CanSkipbyCache(self, gHitSet):
        # Hashing feature is off
        if not GlobalData.gBinCacheSource:
            return False

        if self in gHitSet:
            return True

        return False

    ## Decide whether we can skip the ModuleAutoGen process
    #  If any source file is newer than the module than we cannot skip
    #
    def CanSkip(self):
        # Don't skip if cache feature enabled
        if GlobalData.gUseHashCache or GlobalData.gBinCacheDest or GlobalData.gBinCacheSource:
            return False
        if self.MakeFileDir in GlobalData.gSikpAutoGenCache:
            return True
        if not os.path.exists(self.TimeStampPath):
            return False
        #last creation time of the module
        DstTimeStamp = os.stat(self.TimeStampPath)[8]

        SrcTimeStamp = self.Workspace._SrcTimeStamp
        if SrcTimeStamp > DstTimeStamp:
            return False

        with open(self.TimeStampPath,'r') as f:
            for source in f:
                source = source.rstrip('\n')
                if not os.path.exists(source):
                    return False
                if source not in ModuleAutoGen.TimeDict :
                    ModuleAutoGen.TimeDict[source] = os.stat(source)[8]
                if ModuleAutoGen.TimeDict[source] > DstTimeStamp:
                    return False
        GlobalData.gSikpAutoGenCache.add(self.MakeFileDir)
        return True

    @cached_property
    def TimeStampPath(self):
        return os.path.join(self.MakeFileDir, 'AutoGenTimeStamp')
