## @file
# Generate AutoGen.h, AutoGen.c and *.depex files
#
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution.  The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#

## Import Modules
#
import Common.LongFilePathOs as os
import re
import os.path as path
import copy
import uuid

import GenC
import GenMake
import GenDepex
from StringIO import StringIO

from StrGather import *
from BuildEngine import BuildRule

from Common.LongFilePathSupport import CopyLongFilePath
from Common.BuildToolError import *
from Common.DataType import *
from Common.Misc import *
from Common.String import *
import Common.GlobalData as GlobalData
from GenFds.FdfParser import *
from CommonDataClass.CommonClass import SkuInfoClass
from Workspace.BuildClassObject import *
from GenPatchPcdTable.GenPatchPcdTable import parsePcdInfoFromMapFile
import Common.VpdInfoFile as VpdInfoFile
from GenPcdDb import CreatePcdDatabaseCode
from Workspace.MetaFileCommentParser import UsageList
from Common.MultipleWorkspace import MultipleWorkspace as mws
import InfSectionParser
import datetime
from GenVar import VariableMgr,var_info

## Regular expression for splitting Dependency Expression string into tokens
gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")

#
# 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*})")

## Mapping Makefile type
gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}


## Build rule configuration file
gDefaultBuildRuleFile = 'build_rule.txt'

## Tools definition configuration file
gDefaultToolsDefFile = 'tools_def.txt'

## Build rule default version
AutoGenReqBuildRuleVerNum = "0.1"

## 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"

#
# 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}

${tail_comments}

[BuildOptions.${module_arch}]
## @AsBuilt${BEGIN}
##   ${flags_item}${END}
""")

## Base class for AutoGen
#
#   This class just implements the cache mechanism of AutoGen objects.
#
class AutoGen(object):
    # database to maintain the objects of xxxAutoGen
    _CACHE_ = {}    # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}

    ## Factory method
    #
    #   @param  Class           class object of real AutoGen class
    #                           (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
    #   @param  Workspace       Workspace directory or WorkspaceAutoGen object
    #   @param  MetaFile        The path of meta file
    #   @param  Target          Build target
    #   @param  Toolchain       Tool chain name
    #   @param  Arch            Target arch
    #   @param  *args           The specific class related parameters
    #   @param  **kwargs        The specific class related dict parameters
    #
    def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):
        # check if the object has been created
        Key = (Target, Toolchain)
        if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \
           or MetaFile not in Class._CACHE_[Key][Arch]:
            AutoGenObject = super(AutoGen, Class).__new__(Class)
            # call real constructor
            if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):
                return None
            if Key not in Class._CACHE_:
                Class._CACHE_[Key] = {}
            if Arch not in Class._CACHE_[Key]:
                Class._CACHE_[Key][Arch] = {}
            Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject
        else:
            AutoGenObject = Class._CACHE_[Key][Arch][MetaFile]

        return AutoGenObject

    ## hash() operator
    #
    #  The file path of platform file will be used to represent hash value of this object
    #
    #   @retval int     Hash value of the file path of platform file
    #
    def __hash__(self):
        return hash(self.MetaFile)

    ## str() operator
    #
    #  The file path of platform file will be used to represent this object
    #
    #   @retval string  String of platform file path
    #
    def __str__(self):
        return str(self.MetaFile)

    ## "==" operator
    def __eq__(self, Other):
        return Other and self.MetaFile == Other

## Workspace AutoGen class
#
#   This class is used mainly to control the whole platform build for different
# architecture. This class will generate top level makefile.
#
class WorkspaceAutoGen(AutoGen):
    ## Real constructor of WorkspaceAutoGen
    #
    # This method behaves the same as __init__ except that it needs explicit invoke
    # (in super class's __new__ method)
    #
    #   @param  WorkspaceDir            Root directory of workspace
    #   @param  ActivePlatform          Meta-file of active platform
    #   @param  Target                  Build target
    #   @param  Toolchain               Tool chain name
    #   @param  ArchList                List of architecture of current build
    #   @param  MetaFileDb              Database containing meta-files
    #   @param  BuildConfig             Configuration of build
    #   @param  ToolDefinition          Tool chain definitions
    #   @param  FlashDefinitionFile     File of flash definition
    #   @param  Fds                     FD list to be generated
    #   @param  Fvs                     FV list to be generated
    #   @param  Caps                    Capsule list to be generated
    #   @param  SkuId                   SKU id from command line
    #
    def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,
              BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=None, Fvs=None, Caps=None, SkuId='', UniFlag=None,
              Progress=None, BuildModule=None):
        if Fds is None:
            Fds = []
        if Fvs is None:
            Fvs = []
        if Caps is None:
            Caps = []
        self.BuildDatabase  = MetaFileDb
        self.MetaFile       = ActivePlatform
        self.WorkspaceDir   = WorkspaceDir
        self.Platform       = self.BuildDatabase[self.MetaFile, 'COMMON', Target, Toolchain]
        GlobalData.gActivePlatform = self.Platform
        self.BuildTarget    = Target
        self.ToolChain      = Toolchain
        self.ArchList       = ArchList
        self.SkuId          = SkuId
        self.UniFlag        = UniFlag

        self.TargetTxt      = BuildConfig
        self.ToolDef        = ToolDefinition
        self.FdfFile        = FlashDefinitionFile
        self.FdTargetList   = Fds
        self.FvTargetList   = Fvs
        self.CapTargetList  = Caps
        self.AutoGenObjectList = []

        # there's many relative directory operations, so ...
        os.chdir(self.WorkspaceDir)

        #
        # Merge Arch
        #
        if not self.ArchList:
            ArchList = set(self.Platform.SupArchList)
        else:
            ArchList = set(self.ArchList) & set(self.Platform.SupArchList)
        if not ArchList:
            EdkLogger.error("build", PARAMETER_INVALID,
                            ExtraData = "Invalid ARCH specified. [Valid ARCH: %s]" % (" ".join(self.Platform.SupArchList)))
        elif self.ArchList and len(ArchList) != len(self.ArchList):
            SkippedArchList = set(self.ArchList).symmetric_difference(set(self.Platform.SupArchList))
            EdkLogger.verbose("\nArch [%s] is ignored because the platform supports [%s] only!"
                              % (" ".join(SkippedArchList), " ".join(self.Platform.SupArchList)))
        self.ArchList = tuple(ArchList)

        # Validate build target
        if self.BuildTarget not in self.Platform.BuildTargets:
            EdkLogger.error("build", PARAMETER_INVALID,
                            ExtraData="Build target [%s] is not supported by the platform. [Valid target: %s]"
                                      % (self.BuildTarget, " ".join(self.Platform.BuildTargets)))

        
        # parse FDF file to get PCDs in it, if any
        if not self.FdfFile:
            self.FdfFile = self.Platform.FlashDefinition

        EdkLogger.info("")
        if self.ArchList:
            EdkLogger.info('%-16s = %s' % ("Architecture(s)", ' '.join(self.ArchList)))
        EdkLogger.info('%-16s = %s' % ("Build target", self.BuildTarget))
        EdkLogger.info('%-16s = %s' % ("Toolchain", self.ToolChain))

        EdkLogger.info('\n%-24s = %s' % ("Active Platform", self.Platform))
        if BuildModule:
            EdkLogger.info('%-24s = %s' % ("Active Module", BuildModule))

        if self.FdfFile:
            EdkLogger.info('%-24s = %s' % ("Flash Image Definition", self.FdfFile))

        EdkLogger.verbose("\nFLASH_DEFINITION = %s" % self.FdfFile)

#         if Progress:
#             Progress.Start("\nProcessing meta-data")

        if self.FdfFile:
            #
            # Mark now build in AutoGen Phase
            #
            GlobalData.gAutoGenPhase = True
            Fdf = FdfParser(self.FdfFile.Path)
            Fdf.ParseFile()
            GlobalData.gFdfParser = Fdf
            GlobalData.gAutoGenPhase = False
            PcdSet = Fdf.Profile.PcdDict
            if Fdf.CurrentFdName and Fdf.CurrentFdName in Fdf.Profile.FdDict:
                FdDict = Fdf.Profile.FdDict[Fdf.CurrentFdName]
                for FdRegion in FdDict.RegionList:
                    if str(FdRegion.RegionType) is 'FILE' and self.Platform.VpdToolGuid in str(FdRegion.RegionDataList):
                        if int(FdRegion.Offset) % 8 != 0:
                            EdkLogger.error("build", FORMAT_INVALID, 'The VPD Base Address %s must be 8-byte aligned.' % (FdRegion.Offset))
            ModuleList = Fdf.Profile.InfList
            self.FdfProfile = Fdf.Profile
            for fvname in self.FvTargetList:
                if fvname.upper() not in self.FdfProfile.FvDict:
                    EdkLogger.error("build", OPTION_VALUE_INVALID,
                                    "No such an FV in FDF file: %s" % fvname)

            # In DSC file may use FILE_GUID to override the module, then in the Platform.Modules use FILE_GUIDmodule.inf as key,
            # but the path (self.MetaFile.Path) is the real path
            for key in self.FdfProfile.InfDict:
                if key == 'ArchTBD':
                    Platform_cache = {}
                    MetaFile_cache = {}
                    for Arch in self.ArchList:
                        Platform_cache[Arch] = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]
                        MetaFile_cache[Arch] = []
                        for Pkey in Platform_cache[Arch].Modules.keys():
                            MetaFile_cache[Arch].append(Platform_cache[Arch].Modules[Pkey].MetaFile)
                    for Inf in self.FdfProfile.InfDict[key]:
                        ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)
                        for Arch in self.ArchList:
                            if ModuleFile in MetaFile_cache[Arch]:
                                break
                        else:
                            ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]
                            if not ModuleData.IsBinaryModule:
                                EdkLogger.error('build', PARSER_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile)

                else:
                    for Arch in self.ArchList:
                        if Arch == key:
                            Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]
                            MetaFileList = []
                            for Pkey in Platform.Modules.keys():
                                MetaFileList.append(Platform.Modules[Pkey].MetaFile)
                            for Inf in self.FdfProfile.InfDict[key]:
                                ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)
                                if ModuleFile in MetaFileList:
                                    continue
                                ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]
                                if not ModuleData.IsBinaryModule:
                                    EdkLogger.error('build', PARSER_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile)

        else:
            PcdSet = {}
            ModuleList = []
            self.FdfProfile = None
            if self.FdTargetList:
                EdkLogger.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self.FdTargetList))
                self.FdTargetList = []
            if self.FvTargetList:
                EdkLogger.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self.FvTargetList))
                self.FvTargetList = []
            if self.CapTargetList:
                EdkLogger.info("No flash definition file found. Capsule [%s] will be ignored." % " ".join(self.CapTargetList))
                self.CapTargetList = []

        # apply SKU and inject PCDs from Flash Definition file
        for Arch in self.ArchList:
            Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]

            DecPcds = {}
            DecPcdsKey = set()
            PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
            if GlobalData.BuildOptionPcd:
                for i, pcd in enumerate(GlobalData.BuildOptionPcd):
                    if type(pcd) is tuple:
                        continue
                    (pcdname, pcdvalue) = pcd.split('=')
                    if not pcdvalue:
                        EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))
                    if '.' in pcdname:
                        (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')
                        HasTokenSpace = True
                    else:
                        TokenCName = pcdname
                        TokenSpaceGuidCName = ''
                        HasTokenSpace = False
                    TokenSpaceGuidCNameList = []
                    FoundFlag = False
                    PcdDatumType = ''
                    NewValue = ''
                    for package in PGen.PackageList:
                        for key in package.Pcds:
                            PcdItem = package.Pcds[key]
                            if HasTokenSpace:
                                if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):
                                    PcdDatumType = PcdItem.DatumType
                                    NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
                                    FoundFlag = True
                            else:
                                if PcdItem.TokenCName == TokenCName:
                                    if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
                                        if len (TokenSpaceGuidCNameList) < 1:
                                            TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
                                            PcdDatumType = PcdItem.DatumType
                                            TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
                                            NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
                                            FoundFlag = True
                                        else:
                                            EdkLogger.error(
                                                    'build',
                                                     AUTOGEN_ERROR,
                                                    "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
                                                    )

                    GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)

                    if not FoundFlag:
                        if HasTokenSpace:
                            EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, TokenCName))
                        else:
                            EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (TokenCName))

                    for BuildData in PGen.BuildDatabase._CACHE_.values():
                        if BuildData.Arch != Arch:
                            continue
                        if BuildData.MetaFile.Ext == '.dec':
                            continue
                        for key in BuildData.Pcds:
                            PcdItem = BuildData.Pcds[key]
                            if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName):
                                PcdItem.DefaultValue = NewValue

                    if (TokenCName, TokenSpaceGuidCName) in PcdSet:
                        PcdSet[(TokenCName, TokenSpaceGuidCName)] = NewValue

            SourcePcdDict = {'DynamicEx':[], 'PatchableInModule':[],'Dynamic':[],'FixedAtBuild':[]}
            BinaryPcdDict = {'DynamicEx':[], 'PatchableInModule':[]}
            SourcePcdDict_Keys = SourcePcdDict.keys()
            BinaryPcdDict_Keys = BinaryPcdDict.keys()

            # generate the SourcePcdDict and BinaryPcdDict
            for BuildData in PGen.BuildDatabase._CACHE_.values():
                if BuildData.Arch != Arch:
                    continue
                if BuildData.MetaFile.Ext == '.inf':
                    for key in BuildData.Pcds:
                        if BuildData.Pcds[key].Pending:
                            if key in Platform.Pcds:
                                PcdInPlatform = Platform.Pcds[key]
                                if PcdInPlatform.Type not in [None, '']:
                                    BuildData.Pcds[key].Type = PcdInPlatform.Type

                            if BuildData.MetaFile in Platform.Modules:
                                PlatformModule = Platform.Modules[str(BuildData.MetaFile)]
                                if key in PlatformModule.Pcds:
                                    PcdInPlatform = PlatformModule.Pcds[key]
                                    if PcdInPlatform.Type not in [None, '']:
                                        BuildData.Pcds[key].Type = PcdInPlatform.Type

                        if 'DynamicEx' in BuildData.Pcds[key].Type:
                            if BuildData.IsBinaryModule:
                                if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in BinaryPcdDict['DynamicEx']:
                                    BinaryPcdDict['DynamicEx'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
                            else:
                                if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['DynamicEx']:
                                    SourcePcdDict['DynamicEx'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))

                        elif 'PatchableInModule' in BuildData.Pcds[key].Type:
                            if BuildData.MetaFile.Ext == '.inf':
                                if BuildData.IsBinaryModule:
                                    if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in BinaryPcdDict['PatchableInModule']:
                                        BinaryPcdDict['PatchableInModule'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
                                else:
                                    if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['PatchableInModule']:
                                        SourcePcdDict['PatchableInModule'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))

                        elif 'Dynamic' in BuildData.Pcds[key].Type:
                            if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['Dynamic']:
                                SourcePcdDict['Dynamic'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
                        elif 'FixedAtBuild' in BuildData.Pcds[key].Type:
                            if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['FixedAtBuild']:
                                SourcePcdDict['FixedAtBuild'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
                else:
                    pass
            #
            # A PCD can only use one type for all source modules
            #
            for i in SourcePcdDict_Keys:
                for j in SourcePcdDict_Keys:
                    if i != j:
                        IntersectionList = list(set(SourcePcdDict[i]).intersection(set(SourcePcdDict[j])))
                        if len(IntersectionList) > 0:
                            EdkLogger.error(
                            'build',
                            FORMAT_INVALID,
                            "Building modules from source INFs, following PCD use %s and %s access method. It must be corrected to use only one access method." % (i, j),
                            ExtraData="%s" % '\n\t'.join([str(P[1]+'.'+P[0]) for P in IntersectionList])
                            )
                    else:
                        pass

            #
            # intersection the BinaryPCD for Mixed PCD
            #
            for i in BinaryPcdDict_Keys:
                for j in BinaryPcdDict_Keys:
                    if i != j:
                        IntersectionList = list(set(BinaryPcdDict[i]).intersection(set(BinaryPcdDict[j])))
                        for item in IntersectionList:
                            NewPcd1 = (item[0] + '_' + i, item[1])
                            NewPcd2 = (item[0] + '_' + j, item[1])
                            if item not in GlobalData.MixedPcd:
                                GlobalData.MixedPcd[item] = [NewPcd1, NewPcd2]
                            else:
                                if NewPcd1 not in GlobalData.MixedPcd[item]:
                                    GlobalData.MixedPcd[item].append(NewPcd1)
                                if NewPcd2 not in GlobalData.MixedPcd[item]:
                                    GlobalData.MixedPcd[item].append(NewPcd2)
                    else:
                        pass

            #
            # intersection the SourcePCD and BinaryPCD for Mixed PCD
            #
            for i in SourcePcdDict_Keys:
                for j in BinaryPcdDict_Keys:
                    if i != j:
                        IntersectionList = list(set(SourcePcdDict[i]).intersection(set(BinaryPcdDict[j])))
                        for item in IntersectionList:
                            NewPcd1 = (item[0] + '_' + i, item[1])
                            NewPcd2 = (item[0] + '_' + j, item[1])
                            if item not in GlobalData.MixedPcd:
                                GlobalData.MixedPcd[item] = [NewPcd1, NewPcd2]
                            else:
                                if NewPcd1 not in GlobalData.MixedPcd[item]:
                                    GlobalData.MixedPcd[item].append(NewPcd1)
                                if NewPcd2 not in GlobalData.MixedPcd[item]:
                                    GlobalData.MixedPcd[item].append(NewPcd2)
                    else:
                        pass

            for BuildData in PGen.BuildDatabase._CACHE_.values():
                if BuildData.Arch != Arch:
                    continue
                for key in BuildData.Pcds:
                    for SinglePcd in GlobalData.MixedPcd:
                        if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) == SinglePcd:
                            for item in GlobalData.MixedPcd[SinglePcd]:
                                Pcd_Type = item[0].split('_')[-1]
                                if (Pcd_Type == BuildData.Pcds[key].Type) or (Pcd_Type == TAB_PCDS_DYNAMIC_EX and BuildData.Pcds[key].Type in GenC.gDynamicExPcd) or \
                                   (Pcd_Type == TAB_PCDS_DYNAMIC and BuildData.Pcds[key].Type in GenC.gDynamicPcd):
                                    Value = BuildData.Pcds[key]
                                    Value.TokenCName = BuildData.Pcds[key].TokenCName + '_' + Pcd_Type
                                    if len(key) == 2:
                                        newkey = (Value.TokenCName, key[1])
                                    elif len(key) == 3:
                                        newkey = (Value.TokenCName, key[1], key[2])
                                    del BuildData.Pcds[key]
                                    BuildData.Pcds[newkey] = Value
                                    break
                                else:
                                    pass
                            break
                        else:
                            pass

            # handle the mixed pcd in FDF file
            for key in PcdSet:
                if key in GlobalData.MixedPcd:
                    Value = PcdSet[key]
                    del PcdSet[key]
                    for item in GlobalData.MixedPcd[key]:
                        PcdSet[item] = Value

            #Collect package set information from INF of FDF
            PkgSet = set()
            for Inf in ModuleList:
                ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)
                if ModuleFile in Platform.Modules:
                    continue
                ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]
                PkgSet.update(ModuleData.Packages)
            Pkgs = list(PkgSet) + list(PGen.PackageList)
            for Pkg in Pkgs:
                for Pcd in Pkg.Pcds:
                    DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]
                    DecPcdsKey.add((Pcd[0], Pcd[1], Pcd[2]))

            Platform.SkuName = self.SkuId
            for Name, Guid in PcdSet:
                if (Name, Guid) not in DecPcds:
                    EdkLogger.error(
                        'build',
                        PARSER_ERROR,
                        "PCD (%s.%s) used in FDF is not declared in DEC files." % (Guid, Name),
                        File = self.FdfProfile.PcdFileLineDict[Name, Guid][0],
                        Line = self.FdfProfile.PcdFileLineDict[Name, Guid][1]
                    )
                else:
                    # Check whether Dynamic or DynamicEx PCD used in FDF file. If used, build break and give a error message.
                    if (Name, Guid, TAB_PCDS_FIXED_AT_BUILD) in DecPcdsKey \
                        or (Name, Guid, TAB_PCDS_PATCHABLE_IN_MODULE) in DecPcdsKey \
                        or (Name, Guid, TAB_PCDS_FEATURE_FLAG) in DecPcdsKey:
                        Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])
                        continue
                    elif (Name, Guid, TAB_PCDS_DYNAMIC) in DecPcdsKey or (Name, Guid, TAB_PCDS_DYNAMIC_EX) in DecPcdsKey:
                        EdkLogger.error(
                                'build',
                                PARSER_ERROR,
                                "Using Dynamic or DynamicEx type of PCD [%s.%s] in FDF file is not allowed." % (Guid, Name),
                                File = self.FdfProfile.PcdFileLineDict[Name, Guid][0],
                                Line = self.FdfProfile.PcdFileLineDict[Name, Guid][1]
                        )

            Pa = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
            #
            # Explicitly collect platform's dynamic PCDs
            #
            Pa.CollectPlatformDynamicPcds()
            Pa.CollectFixedAtBuildPcds()
            self.AutoGenObjectList.append(Pa)

        #
        # Check PCDs token value conflict in each DEC file.
        #
        self._CheckAllPcdsTokenValueConflict()

        #
        # Check PCD type and definition between DSC and DEC
        #
        self._CheckPcdDefineAndType()

#         if self.FdfFile:
#             self._CheckDuplicateInFV(Fdf)

        self._BuildDir = None
        self._FvDir = None
        self._MakeFileDir = None
        self._BuildCommand = None

        #
        # Create BuildOptions Macro & PCD metafile, also add the Active Platform and FDF file.
        #
        content = 'gCommandLineDefines: '
        content += str(GlobalData.gCommandLineDefines)
        content += os.linesep
        content += 'BuildOptionPcd: '
        content += str(GlobalData.BuildOptionPcd)
        content += os.linesep
        content += 'Active Platform: '
        content += str(self.Platform)
        content += os.linesep
        if self.FdfFile:
            content += 'Flash Image Definition: '
            content += str(self.FdfFile)
        SaveFileOnChange(os.path.join(self.BuildDir, 'BuildOptions'), content, False)

        #
        # Create PcdToken Number file for Dynamic/DynamicEx Pcd.
        #
        PcdTokenNumber = 'PcdTokenNumber: '
        if Pa.PcdTokenNumber:
            if Pa.DynamicPcdList:
                for Pcd in Pa.DynamicPcdList:
                    PcdTokenNumber += os.linesep
                    PcdTokenNumber += str((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))
                    PcdTokenNumber += ' : '
                    PcdTokenNumber += str(Pa.PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName])
        SaveFileOnChange(os.path.join(self.BuildDir, 'PcdTokenNumber'), PcdTokenNumber, False)

        #
        # Get set of workspace metafiles
        #
        AllWorkSpaceMetaFiles = self._GetMetaFiles(Target, Toolchain, Arch)

        #
        # Retrieve latest modified time of all metafiles
        #
        SrcTimeStamp = 0
        for f in AllWorkSpaceMetaFiles:
            if os.stat(f)[8] > SrcTimeStamp:
                SrcTimeStamp = os.stat(f)[8]
        self._SrcTimeStamp = SrcTimeStamp

        #
        # Write metafile list to build directory
        #
        AutoGenFilePath = os.path.join(self.BuildDir, 'AutoGen')
        if os.path.exists (AutoGenFilePath):
            os.remove(AutoGenFilePath)
        if not os.path.exists(self.BuildDir):
            os.makedirs(self.BuildDir)
        with open(os.path.join(self.BuildDir, 'AutoGen'), 'w+') as file:
            for f in AllWorkSpaceMetaFiles:
                print >> file, f
        return True


    def _GetMetaFiles(self, Target, Toolchain, Arch):
        AllWorkSpaceMetaFiles = set()
        #
        # add fdf
        #
        if self.FdfFile:
            AllWorkSpaceMetaFiles.add (self.FdfFile.Path)
            if self.FdfFile:
                FdfFiles = GlobalData.gFdfParser.GetAllIncludedFile()
                for f in FdfFiles:
                    AllWorkSpaceMetaFiles.add (f.FileName)
        #
        # add dsc
        #
        AllWorkSpaceMetaFiles.add(self.MetaFile.Path)

        #
        # add build_rule.txt & tools_def.txt
        #
        AllWorkSpaceMetaFiles.add(os.path.join(GlobalData.gConfDirectory, gDefaultBuildRuleFile))
        AllWorkSpaceMetaFiles.add(os.path.join(GlobalData.gConfDirectory, gDefaultToolsDefFile))

        # add BuildOption metafile
        #
        AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'BuildOptions'))

        # add PcdToken Number file for Dynamic/DynamicEx Pcd
        #
        AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'PcdTokenNumber'))

        for Arch in self.ArchList:
            Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]
            PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)

            #
            # add dec
            #
            for Package in PGen.PackageList:
                AllWorkSpaceMetaFiles.add(Package.MetaFile.Path)

            #
            # add included dsc
            #
            for filePath in Platform._RawData.IncludedFiles:
                AllWorkSpaceMetaFiles.add(filePath.Path)

        return AllWorkSpaceMetaFiles

    ## _CheckDuplicateInFV() method
    #
    # Check whether there is duplicate modules/files exist in FV section. 
    # The check base on the file GUID;
    #
    def _CheckDuplicateInFV(self, Fdf):
        for Fv in Fdf.Profile.FvDict:
            _GuidDict = {}
            for FfsFile in Fdf.Profile.FvDict[Fv].FfsList:
                if FfsFile.InfFileName and FfsFile.NameGuid == None:
                    #
                    # Get INF file GUID
                    #
                    InfFoundFlag = False
                    for Pa in self.AutoGenObjectList:
                        if InfFoundFlag:
                            break
                        for Module in Pa.ModuleAutoGenList:
                            if path.normpath(Module.MetaFile.File) == path.normpath(FfsFile.InfFileName):
                                InfFoundFlag = True
                                if not Module.Guid.upper() in _GuidDict.keys():
                                    _GuidDict[Module.Guid.upper()] = FfsFile
                                    break
                                else:
                                    EdkLogger.error("build",
                                                    FORMAT_INVALID,
                                                    "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,
                                                                                                                                   FfsFile.CurrentLineContent,
                                                                                                                                   _GuidDict[Module.Guid.upper()].CurrentLineNum,
                                                                                                                                   _GuidDict[Module.Guid.upper()].CurrentLineContent,
                                                                                                                                   Module.Guid.upper()),
                                                    ExtraData=self.FdfFile)
                    #
                    # Some INF files not have entity in DSC file. 
                    #
                    if not InfFoundFlag:
                        if FfsFile.InfFileName.find('$') == -1:
                            InfPath = NormPath(FfsFile.InfFileName)
                            if not os.path.exists(InfPath):
                                EdkLogger.error('build', GENFDS_ERROR, "Non-existant Module %s !" % (FfsFile.InfFileName))

                            PathClassObj = PathClass(FfsFile.InfFileName, self.WorkspaceDir)
                            #
                            # Here we just need to get FILE_GUID from INF file, use 'COMMON' as ARCH attribute. and use 
                            # BuildObject from one of AutoGenObjectList is enough.
                            #
                            InfObj = self.AutoGenObjectList[0].BuildDatabase.WorkspaceDb.BuildObject[PathClassObj, 'COMMON', self.BuildTarget, self.ToolChain]
                            if not InfObj.Guid.upper() in _GuidDict.keys():
                                _GuidDict[InfObj.Guid.upper()] = FfsFile
                            else:
                                EdkLogger.error("build",
                                                FORMAT_INVALID,
                                                "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,
                                                                                                                               FfsFile.CurrentLineContent,
                                                                                                                               _GuidDict[InfObj.Guid.upper()].CurrentLineNum,
                                                                                                                               _GuidDict[InfObj.Guid.upper()].CurrentLineContent,
                                                                                                                               InfObj.Guid.upper()),
                                                ExtraData=self.FdfFile)
                        InfFoundFlag = False

                if FfsFile.NameGuid != None:
                    _CheckPCDAsGuidPattern = re.compile("^PCD\(.+\..+\)$")

                    #
                    # If the NameGuid reference a PCD name. 
                    # The style must match: PCD(xxxx.yyy)
                    #
                    if _CheckPCDAsGuidPattern.match(FfsFile.NameGuid):
                        #
                        # Replace the PCD value.
                        #
                        _PcdName = FfsFile.NameGuid.lstrip("PCD(").rstrip(")")
                        PcdFoundFlag = False
                        for Pa in self.AutoGenObjectList:
                            if not PcdFoundFlag:
                                for PcdItem in Pa.AllPcdList:
                                    if (PcdItem.TokenSpaceGuidCName + "." + PcdItem.TokenCName) == _PcdName:
                                        #
                                        # First convert from CFormatGuid to GUID string
                                        #
                                        _PcdGuidString = GuidStructureStringToGuidString(PcdItem.DefaultValue)

                                        if not _PcdGuidString:
                                            #
                                            # Then try Byte array.
                                            #
                                            _PcdGuidString = GuidStructureByteArrayToGuidString(PcdItem.DefaultValue)

                                        if not _PcdGuidString:
                                            #
                                            # Not Byte array or CFormat GUID, raise error.
                                            #
                                            EdkLogger.error("build",
                                                            FORMAT_INVALID,
                                                            "The format of PCD value is incorrect. PCD: %s , Value: %s\n" % (_PcdName, PcdItem.DefaultValue),
                                                            ExtraData=self.FdfFile)

                                        if not _PcdGuidString.upper() in _GuidDict.keys():
                                            _GuidDict[_PcdGuidString.upper()] = FfsFile
                                            PcdFoundFlag = True
                                            break
                                        else:
                                            EdkLogger.error("build",
                                                            FORMAT_INVALID,
                                                            "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,
                                                                                                                                           FfsFile.CurrentLineContent,
                                                                                                                                           _GuidDict[_PcdGuidString.upper()].CurrentLineNum,
                                                                                                                                           _GuidDict[_PcdGuidString.upper()].CurrentLineContent,
                                                                                                                                           FfsFile.NameGuid.upper()),
                                                            ExtraData=self.FdfFile)

                    if not FfsFile.NameGuid.upper() in _GuidDict.keys():
                        _GuidDict[FfsFile.NameGuid.upper()] = FfsFile
                    else:
                        #
                        # Two raw file GUID conflict.
                        #
                        EdkLogger.error("build",
                                        FORMAT_INVALID,
                                        "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,
                                                                                                                       FfsFile.CurrentLineContent,
                                                                                                                       _GuidDict[FfsFile.NameGuid.upper()].CurrentLineNum,
                                                                                                                       _GuidDict[FfsFile.NameGuid.upper()].CurrentLineContent,
                                                                                                                       FfsFile.NameGuid.upper()),
                                        ExtraData=self.FdfFile)


    def _CheckPcdDefineAndType(self):
        PcdTypeList = [
            "FixedAtBuild", "PatchableInModule", "FeatureFlag",
            "Dynamic", #"DynamicHii", "DynamicVpd",
            "DynamicEx", # "DynamicExHii", "DynamicExVpd"
        ]

        # This dict store PCDs which are not used by any modules with specified arches
        UnusedPcd = sdict()
        for Pa in self.AutoGenObjectList:
            # Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid
            for Pcd in Pa.Platform.Pcds:
                PcdType = Pa.Platform.Pcds[Pcd].Type

                # If no PCD type, this PCD comes from FDF 
                if not PcdType:
                    continue

                # Try to remove Hii and Vpd suffix
                if PcdType.startswith("DynamicEx"):
                    PcdType = "DynamicEx"
                elif PcdType.startswith("Dynamic"):
                    PcdType = "Dynamic"

                for Package in Pa.PackageList:
                    # Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType
                    if (Pcd[0], Pcd[1], PcdType) in Package.Pcds:
                        break
                    for Type in PcdTypeList:
                        if (Pcd[0], Pcd[1], Type) in Package.Pcds:
                            EdkLogger.error(
                                'build',
                                FORMAT_INVALID,
                                "Type [%s] of PCD [%s.%s] in DSC file doesn't match the type [%s] defined in DEC file." \
                                % (Pa.Platform.Pcds[Pcd].Type, Pcd[1], Pcd[0], Type),
                                ExtraData=None
                            )
                            return
                else:
                    UnusedPcd.setdefault(Pcd, []).append(Pa.Arch)

        for Pcd in UnusedPcd:
            EdkLogger.warn(
                'build',
                "The PCD was not specified by any INF module in the platform for the given architecture.\n"
                "\tPCD: [%s.%s]\n\tPlatform: [%s]\n\tArch: %s"
                % (Pcd[1], Pcd[0], os.path.basename(str(self.MetaFile)), str(UnusedPcd[Pcd])),
                ExtraData=None
            )

    def __repr__(self):
        return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList))

    ## Return the directory to store FV files
    def _GetFvDir(self):
        if self._FvDir == None:
            self._FvDir = path.join(self.BuildDir, 'FV')
        return self._FvDir

    ## Return the directory to store all intermediate and final files built
    def _GetBuildDir(self):
        return self.AutoGenObjectList[0].BuildDir

    ## Return the build output directory platform specifies
    def _GetOutputDir(self):
        return self.Platform.OutputDirectory

    ## Return platform name
    def _GetName(self):
        return self.Platform.PlatformName

    ## Return meta-file GUID
    def _GetGuid(self):
        return self.Platform.Guid

    ## Return platform version
    def _GetVersion(self):
        return self.Platform.Version

    ## Return paths of tools
    def _GetToolDefinition(self):
        return self.AutoGenObjectList[0].ToolDefinition

    ## Return directory of platform makefile
    #
    #   @retval     string  Makefile directory
    #
    def _GetMakeFileDir(self):
        if self._MakeFileDir == None:
            self._MakeFileDir = self.BuildDir
        return self._MakeFileDir

    ## Return build command string
    #
    #   @retval     string  Build command string
    #
    def _GetBuildCommand(self):
        if self._BuildCommand == None:
            # BuildCommand should be all the same. So just get one from platform AutoGen
            self._BuildCommand = self.AutoGenObjectList[0].BuildCommand
        return self._BuildCommand

    ## Check the PCDs token value conflict in each DEC file.
    #
    # Will cause build break and raise error message while two PCDs conflict.
    # 
    # @return  None
    #
    def _CheckAllPcdsTokenValueConflict(self):
        for Pa in self.AutoGenObjectList:
            for Package in Pa.PackageList:
                PcdList = Package.Pcds.values()
                PcdList.sort(lambda x, y: cmp(int(x.TokenValue, 0), int(y.TokenValue, 0))) 
                Count = 0
                while (Count < len(PcdList) - 1) :
                    Item = PcdList[Count]
                    ItemNext = PcdList[Count + 1]
                    #
                    # Make sure in the same token space the TokenValue should be unique
                    #
                    if (int(Item.TokenValue, 0) == int(ItemNext.TokenValue, 0)):
                        SameTokenValuePcdList = []
                        SameTokenValuePcdList.append(Item)
                        SameTokenValuePcdList.append(ItemNext)
                        RemainPcdListLength = len(PcdList) - Count - 2
                        for ValueSameCount in range(RemainPcdListLength):
                            if int(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount].TokenValue, 0) == int(Item.TokenValue, 0):
                                SameTokenValuePcdList.append(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount])
                            else:
                                break;
                        #
                        # Sort same token value PCD list with TokenGuid and TokenCName
                        #
                        SameTokenValuePcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))
                        SameTokenValuePcdListCount = 0
                        while (SameTokenValuePcdListCount < len(SameTokenValuePcdList) - 1):
                            Flag = False
                            TemListItem = SameTokenValuePcdList[SameTokenValuePcdListCount]
                            TemListItemNext = SameTokenValuePcdList[SameTokenValuePcdListCount + 1]

                            if (TemListItem.TokenSpaceGuidCName == TemListItemNext.TokenSpaceGuidCName) and (TemListItem.TokenCName != TemListItemNext.TokenCName):
                                for PcdItem in GlobalData.MixedPcd:
                                    if (TemListItem.TokenCName, TemListItem.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem] or \
                                        (TemListItemNext.TokenCName, TemListItemNext.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
                                        Flag = True
                                if not Flag:
                                    EdkLogger.error(
                                                'build',
                                                FORMAT_INVALID,
                                                "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\
                                                % (TemListItem.TokenValue, TemListItem.TokenSpaceGuidCName, TemListItem.TokenCName, TemListItemNext.TokenSpaceGuidCName, TemListItemNext.TokenCName, Package),
                                                ExtraData=None
                                                )
                            SameTokenValuePcdListCount += 1
                        Count += SameTokenValuePcdListCount
                    Count += 1

                PcdList = Package.Pcds.values()
                PcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))
                Count = 0
                while (Count < len(PcdList) - 1) :
                    Item = PcdList[Count]
                    ItemNext = PcdList[Count + 1]
                    #
                    # Check PCDs with same TokenSpaceGuidCName.TokenCName have same token value as well.
                    #
                    if (Item.TokenSpaceGuidCName == ItemNext.TokenSpaceGuidCName) and (Item.TokenCName == ItemNext.TokenCName) and (int(Item.TokenValue, 0) != int(ItemNext.TokenValue, 0)):
                        EdkLogger.error(
                                    'build',
                                    FORMAT_INVALID,
                                    "The TokenValue [%s] of PCD [%s.%s] in %s defined in two places should be same as well."\
                                    % (Item.TokenValue, Item.TokenSpaceGuidCName, Item.TokenCName, Package),
                                    ExtraData=None
                                    )
                    Count += 1
    ## Generate fds command
    def _GenFdsCommand(self):
        return (GenMake.TopLevelMakefile(self)._TEMPLATE_.Replace(GenMake.TopLevelMakefile(self)._TemplateDict)).strip()

    ## Create makefile for the platform and modules in it
    #
    #   @param      CreateDepsMakeFile      Flag indicating if the makefile for
    #                                       modules will be created as well
    #
    def CreateMakeFile(self, CreateDepsMakeFile=False):
        if CreateDepsMakeFile:
            for Pa in self.AutoGenObjectList:
                Pa.CreateMakeFile(CreateDepsMakeFile)

    ## Create autogen code for platform and modules
    #
    #  Since there's no autogen code for platform, this method will do nothing
    #  if CreateModuleCodeFile is set to False.
    #
    #   @param      CreateDepsCodeFile      Flag indicating if creating module's
    #                                       autogen code file or not
    #
    def CreateCodeFile(self, CreateDepsCodeFile=False):
        if not CreateDepsCodeFile:
            return
        for Pa in self.AutoGenObjectList:
            Pa.CreateCodeFile(CreateDepsCodeFile)

    ## Create AsBuilt INF file the platform
    #
    def CreateAsBuiltInf(self):
        return

    Name                = property(_GetName)
    Guid                = property(_GetGuid)
    Version             = property(_GetVersion)
    OutputDir           = property(_GetOutputDir)

    ToolDefinition      = property(_GetToolDefinition)       # toolcode : tool path

    BuildDir            = property(_GetBuildDir)
    FvDir               = property(_GetFvDir)
    MakeFileDir         = property(_GetMakeFileDir)
    BuildCommand        = property(_GetBuildCommand)
    GenFdsCommand       = property(_GenFdsCommand)

## AutoGen class for platform
#
#  PlatformAutoGen class will process the original information in platform
#  file in order to generate makefile for platform.
#
class PlatformAutoGen(AutoGen):
    #
    # Used to store all PCDs for both PEI and DXE phase, in order to generate 
    # correct PCD database
    # 
    _DynaPcdList_ = []
    _NonDynaPcdList_ = []
    _PlatformPcds = {}
    
    #
    # The priority list while override build option 
    #
    PrioList = {"0x11111"  : 16,     #  TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest)
                "0x01111"  : 15,     #  ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
                "0x10111"  : 14,     #  TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE
                "0x00111"  : 13,     #  ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE 
                "0x11011"  : 12,     #  TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
                "0x01011"  : 11,     #  ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
                "0x10011"  : 10,     #  TARGET_*********_****_COMMANDTYPE_ATTRIBUTE
                "0x00011"  : 9,      #  ******_*********_****_COMMANDTYPE_ATTRIBUTE
                "0x11101"  : 8,      #  TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE
                "0x01101"  : 7,      #  ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE
                "0x10101"  : 6,      #  TARGET_*********_ARCH_***********_ATTRIBUTE
                "0x00101"  : 5,      #  ******_*********_ARCH_***********_ATTRIBUTE
                "0x11001"  : 4,      #  TARGET_TOOLCHAIN_****_***********_ATTRIBUTE
                "0x01001"  : 3,      #  ******_TOOLCHAIN_****_***********_ATTRIBUTE
                "0x10001"  : 2,      #  TARGET_*********_****_***********_ATTRIBUTE
                "0x00001"  : 1}      #  ******_*********_****_***********_ATTRIBUTE (Lowest)

    ## The real constructor of PlatformAutoGen
    #
    #  This method is not supposed to be called by users of PlatformAutoGen. It's
    #  only used by factory method __new__() to do real initialization work for an
    #  object of PlatformAutoGen
    #
    #   @param      Workspace       WorkspaceAutoGen object
    #   @param      PlatformFile    Platform file (DSC file)
    #   @param      Target          Build target (DEBUG, RELEASE)
    #   @param      Toolchain       Name of tool chain
    #   @param      Arch            arch of the platform supports
    #
    def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):
        EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch))
        GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target)

        self.MetaFile = PlatformFile
        self.Workspace = Workspace
        self.WorkspaceDir = Workspace.WorkspaceDir
        self.ToolChain = Toolchain
        self.BuildTarget = Target
        self.Arch = Arch
        self.SourceDir = PlatformFile.SubDir
        self.SourceOverrideDir = None
        self.FdTargetList = self.Workspace.FdTargetList
        self.FvTargetList = self.Workspace.FvTargetList
        self.AllPcdList = []
        # get the original module/package/platform objects
        self.BuildDatabase = Workspace.BuildDatabase
        self.DscBuildDataObj = Workspace.Platform

        # flag indicating if the makefile/C-code file has been created or not
        self.IsMakeFileCreated  = False
        self.IsCodeFileCreated  = False

        self._Platform   = None
        self._Name       = None
        self._Guid       = None
        self._Version    = None

        self._BuildRule = None
        self._SourceDir = None
        self._BuildDir = None
        self._OutputDir = None
        self._FvDir = None
        self._MakeFileDir = None
        self._FdfFile = None

        self._PcdTokenNumber = None    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
        self._DynamicPcdList = None    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
        self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
        self._NonDynamicPcdDict = {}

        self._ToolDefinitions = None
        self._ToolDefFile = None          # toolcode : tool path
        self._ToolChainFamily = None
        self._BuildRuleFamily = None
        self._BuildOption = None          # toolcode : option
        self._EdkBuildOption = None       # edktoolcode : option
        self._EdkIIBuildOption = None     # edkiitoolcode : option
        self._PackageList = None
        self._ModuleAutoGenList  = None
        self._LibraryAutoGenList = None
        self._BuildCommand = None
        self._AsBuildInfList = []
        self._AsBuildModuleList = []
        if GlobalData.gFdfParser != None:
            self._AsBuildInfList = GlobalData.gFdfParser.Profile.InfList
            for Inf in self._AsBuildInfList:
                InfClass = PathClass(NormPath(Inf), GlobalData.gWorkspace, self.Arch)
                M = self.BuildDatabase[InfClass, self.Arch, self.BuildTarget, self.ToolChain]
                if not M.IsSupportedArch:
                    continue
                self._AsBuildModuleList.append(InfClass)
        # get library/modules for build
        self.LibraryBuildDirectoryList = []
        self.ModuleBuildDirectoryList = []
        return True

    def __repr__(self):
        return "%s [%s]" % (self.MetaFile, self.Arch)

    ## Create autogen code for platform and modules
    #
    #  Since there's no autogen code for platform, this method will do nothing
    #  if CreateModuleCodeFile is set to False.
    #
    #   @param      CreateModuleCodeFile    Flag indicating if creating module's
    #                                       autogen code file or not
    #
    def CreateCodeFile(self, CreateModuleCodeFile=False):
        # only module has code to be greated, so do nothing if CreateModuleCodeFile is False
        if self.IsCodeFileCreated or not CreateModuleCodeFile:
            return

        for Ma in self.ModuleAutoGenList:
            Ma.CreateCodeFile(True)

        # don't do this twice
        self.IsCodeFileCreated = True

    ## Generate Fds Command
    def _GenFdsCommand(self):
        return self.Workspace.GenFdsCommand

    ## Create makefile for the platform and mdoules in it
    #
    #   @param      CreateModuleMakeFile    Flag indicating if the makefile for
    #                                       modules will be created as well
    #
    def CreateMakeFile(self, CreateModuleMakeFile=False):
        if CreateModuleMakeFile:
            for ModuleFile in self.Platform.Modules:
                Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,
                                   self.ToolChain, self.Arch, self.MetaFile)
                Ma.CreateMakeFile(True)
                #Ma.CreateAsBuiltInf()

        # no need to create makefile for the platform more than once
        if self.IsMakeFileCreated:
            return

        # create library/module build dirs for platform
        Makefile = GenMake.PlatformMakefile(self)
        self.LibraryBuildDirectoryList = Makefile.GetLibraryBuildDirectoryList()
        self.ModuleBuildDirectoryList = Makefile.GetModuleBuildDirectoryList()

        self.IsMakeFileCreated = True

    ## Deal with Shared FixedAtBuild Pcds
    #
    def CollectFixedAtBuildPcds(self):
        for LibAuto in self.LibraryAutoGenList:
            FixedAtBuildPcds = {}  
            ShareFixedAtBuildPcdsSameValue = {} 
            for Module in LibAuto._ReferenceModules:                
                for Pcd in Module.FixedAtBuildPcds + LibAuto.FixedAtBuildPcds:
                    key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))  
                    if key not in FixedAtBuildPcds:
                        ShareFixedAtBuildPcdsSameValue[key] = True
                        FixedAtBuildPcds[key] = Pcd.DefaultValue
                    else:
                        if FixedAtBuildPcds[key] != Pcd.DefaultValue:
                            ShareFixedAtBuildPcdsSameValue[key] = False      
            for Pcd in LibAuto.FixedAtBuildPcds:
                key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))
                if (Pcd.TokenCName,Pcd.TokenSpaceGuidCName) not in self.NonDynamicPcdDict:
                    continue
                else:
                    DscPcd = self.NonDynamicPcdDict[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)]
                    if DscPcd.Type != "FixedAtBuild":
                        continue
                if key in ShareFixedAtBuildPcdsSameValue and ShareFixedAtBuildPcdsSameValue[key]:                    
                    LibAuto.ConstPcd[key] = Pcd.DefaultValue
                    
    def CollectVariables(self, DynamicPcdSet):
        VariableInfo = VariableMgr(self.DscBuildDataObj._GetDefaultStores(),self.DscBuildDataObj._GetSkuIds())
        Index = 0
        for Pcd in DynamicPcdSet:
            pcdname = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))
            for SkuName in Pcd.SkuInfoList:
                Sku = Pcd.SkuInfoList[SkuName]
                SkuId = Sku.SkuId
                if SkuId == None or SkuId == '':
                    continue
                if len(Sku.VariableName) > 0:
                    VariableGuidStructure = Sku.VariableGuidValue
                    VariableGuid = GuidStructureStringToGuidString(VariableGuidStructure)
                    if Pcd.Phase == "DXE":
                        for StorageName in Sku.DefaultStoreDict:
                            VariableInfo.append_variable(var_info(Index,pcdname,StorageName,SkuName, StringToArray(Sku.VariableName),VariableGuid, Sku.VariableAttribute , Pcd.DefaultValue,Sku.DefaultStoreDict[StorageName],Pcd.DatumType))
            Index += 1    
        return VariableInfo
    ## Collect dynamic PCDs
    #
    #  Gather dynamic PCDs list from each module and their settings from platform
    #  This interface should be invoked explicitly when platform action is created.
    #
    def CollectPlatformDynamicPcds(self):
        # Override the platform Pcd's value by build option
        if GlobalData.BuildOptionPcd:
            for key in self.Platform.Pcds:
                PlatformPcd = self.Platform.Pcds[key]
                for PcdItem in GlobalData.BuildOptionPcd:
                    if (PlatformPcd.TokenSpaceGuidCName, PlatformPcd.TokenCName) == (PcdItem[0], PcdItem[1]):
                        PlatformPcd.DefaultValue = PcdItem[2]
                        if PlatformPcd.SkuInfoList:
                            Sku = PlatformPcd.SkuInfoList[PlatformPcd.SkuInfoList.keys()[0]]
                            Sku.DefaultValue = PcdItem[2]
                        break

        for key in self.Platform.Pcds:
            for SinglePcd in GlobalData.MixedPcd:
                if (self.Platform.Pcds[key].TokenCName, self.Platform.Pcds[key].TokenSpaceGuidCName) == SinglePcd:
                    for item in GlobalData.MixedPcd[SinglePcd]:
                        Pcd_Type = item[0].split('_')[-1]
                        if (Pcd_Type == self.Platform.Pcds[key].Type) or (Pcd_Type == TAB_PCDS_DYNAMIC_EX and self.Platform.Pcds[key].Type in GenC.gDynamicExPcd) or \
                           (Pcd_Type == TAB_PCDS_DYNAMIC and self.Platform.Pcds[key].Type in GenC.gDynamicPcd):
                            Value = self.Platform.Pcds[key]
                            Value.TokenCName = self.Platform.Pcds[key].TokenCName + '_' + Pcd_Type
                            if len(key) == 2:
                                newkey = (Value.TokenCName, key[1])
                            elif len(key) == 3:
                                newkey = (Value.TokenCName, key[1], key[2])
                            del self.Platform.Pcds[key]
                            self.Platform.Pcds[newkey] = Value
                            break
                        else:
                            pass
                    break
                else:
                    pass

        # for gathering error information
        NoDatumTypePcdList = set()
        PcdNotInDb = []
        self._GuidValue = {}
        FdfModuleList = []
        for InfName in self._AsBuildInfList:
            InfName = mws.join(self.WorkspaceDir, InfName)
            FdfModuleList.append(os.path.normpath(InfName))
        for F in self.Platform.Modules.keys():
            M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile)
            #GuidValue.update(M.Guids)
            
            self.Platform.Modules[F].M = M

            for PcdFromModule in M.ModulePcdList + M.LibraryPcdList:
                # make sure that the "VOID*" kind of datum has MaxDatumSize set
                if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']:
                    NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, F))

                # Check the PCD from Binary INF or Source INF
                if M.IsBinaryModule == True:
                    PcdFromModule.IsFromBinaryInf = True

                # Check the PCD from DSC or not 
                if (PcdFromModule.TokenCName, PcdFromModule.TokenSpaceGuidCName) in self.Platform.Pcds.keys():
                    PcdFromModule.IsFromDsc = True
                else:
                    PcdFromModule.IsFromDsc = False
                if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:
                    if F.Path not in FdfModuleList:
                        # If one of the Source built modules listed in the DSC is not listed 
                        # in FDF modules, and the INF lists a PCD can only use the PcdsDynamic 
                        # access method (it is only listed in the DEC file that declares the 
                        # PCD as PcdsDynamic), then build tool will report warning message
                        # notify the PI that they are attempting to build a module that must 
                        # be included in a flash image in order to be functional. These Dynamic 
                        # PCD will not be added into the Database unless it is used by other 
                        # modules that are included in the FDF file.
                        if PcdFromModule.Type in GenC.gDynamicPcd and \
                            PcdFromModule.IsFromBinaryInf == False:
                            # Print warning message to let the developer make a determine.
                            if PcdFromModule not in PcdNotInDb:
                                PcdNotInDb.append(PcdFromModule)
                            continue
                        # If one of the Source built modules listed in the DSC is not listed in 
                        # FDF modules, and the INF lists a PCD can only use the PcdsDynamicEx 
                        # access method (it is only listed in the DEC file that declares the 
                        # PCD as PcdsDynamicEx), then DO NOT break the build; DO NOT add the 
                        # PCD to the Platform's PCD Database.
                        if PcdFromModule.Type in GenC.gDynamicExPcd:
                            if PcdFromModule not in PcdNotInDb:
                                PcdNotInDb.append(PcdFromModule)
                            continue
                    #
                    # If a dynamic PCD used by a PEM module/PEI module & DXE module,
                    # it should be stored in Pcd PEI database, If a dynamic only
                    # used by DXE module, it should be stored in DXE PCD database.
                    # The default Phase is DXE
                    #
                    if M.ModuleType in ["PEIM", "PEI_CORE"]:
                        PcdFromModule.Phase = "PEI"
                    if PcdFromModule not in self._DynaPcdList_:
                        self._DynaPcdList_.append(PcdFromModule)
                    elif PcdFromModule.Phase == 'PEI':
                        # overwrite any the same PCD existing, if Phase is PEI
                        Index = self._DynaPcdList_.index(PcdFromModule)
                        self._DynaPcdList_[Index] = PcdFromModule
                elif PcdFromModule not in self._NonDynaPcdList_:
                    self._NonDynaPcdList_.append(PcdFromModule)
                elif PcdFromModule in self._NonDynaPcdList_ and PcdFromModule.IsFromBinaryInf == True:
                    Index = self._NonDynaPcdList_.index(PcdFromModule)
                    if self._NonDynaPcdList_[Index].IsFromBinaryInf == False:
                        #The PCD from Binary INF will override the same one from source INF
                        self._NonDynaPcdList_.remove (self._NonDynaPcdList_[Index])
                        PcdFromModule.Pending = False
                        self._NonDynaPcdList_.append (PcdFromModule)
        # Parse the DynamicEx PCD from the AsBuild INF module list of FDF.
        DscModuleList = []
        for ModuleInf in self.Platform.Modules.keys():
            DscModuleList.append (os.path.normpath(ModuleInf.Path))
        # add the PCD from modules that listed in FDF but not in DSC to Database 
        for InfName in FdfModuleList:
            if InfName not in DscModuleList:
                InfClass = PathClass(InfName)
                M = self.BuildDatabase[InfClass, self.Arch, self.BuildTarget, self.ToolChain]
                # If a module INF in FDF but not in current arch's DSC module list, it must be module (either binary or source) 
                # for different Arch. PCDs in source module for different Arch is already added before, so skip the source module here. 
                # For binary module, if in current arch, we need to list the PCDs into database.   
                if not M.IsSupportedArch:
                    continue
                # Override the module PCD setting by platform setting
                ModulePcdList = self.ApplyPcdSetting(M, M.Pcds)
                for PcdFromModule in ModulePcdList:
                    PcdFromModule.IsFromBinaryInf = True
                    PcdFromModule.IsFromDsc = False
                    # Only allow the DynamicEx and Patchable PCD in AsBuild INF
                    if PcdFromModule.Type not in GenC.gDynamicExPcd and PcdFromModule.Type not in TAB_PCDS_PATCHABLE_IN_MODULE:
                        EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",
                                        File=self.MetaFile,
                                        ExtraData="\n\tExisted %s PCD %s in:\n\t\t%s\n"
                                        % (PcdFromModule.Type, PcdFromModule.TokenCName, InfName))
                    # make sure that the "VOID*" kind of datum has MaxDatumSize set
                    if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']:
                        NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, InfName))
                    if M.ModuleType in ["PEIM", "PEI_CORE"]:
                        PcdFromModule.Phase = "PEI"
                    if PcdFromModule not in self._DynaPcdList_ and PcdFromModule.Type in GenC.gDynamicExPcd:
                        self._DynaPcdList_.append(PcdFromModule)
                    elif PcdFromModule not in self._NonDynaPcdList_ and PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE:
                        self._NonDynaPcdList_.append(PcdFromModule)
                    if PcdFromModule in self._DynaPcdList_ and PcdFromModule.Phase == 'PEI' and PcdFromModule.Type in GenC.gDynamicExPcd:
                        # Overwrite the phase of any the same PCD existing, if Phase is PEI.
                        # It is to solve the case that a dynamic PCD used by a PEM module/PEI 
                        # module & DXE module at a same time.
                        # Overwrite the type of the PCDs in source INF by the type of AsBuild
                        # INF file as DynamicEx. 
                        Index = self._DynaPcdList_.index(PcdFromModule)
                        self._DynaPcdList_[Index].Phase = PcdFromModule.Phase
                        self._DynaPcdList_[Index].Type = PcdFromModule.Type
        for PcdFromModule in self._NonDynaPcdList_:
            # If a PCD is not listed in the DSC file, but binary INF files used by 
            # this platform all (that use this PCD) list the PCD in a [PatchPcds] 
            # section, AND all source INF files used by this platform the build 
            # that use the PCD list the PCD in either a [Pcds] or [PatchPcds] 
            # section, then the tools must NOT add the PCD to the Platform's PCD
            # Database; the build must assign the access method for this PCD as 
            # PcdsPatchableInModule.
            if PcdFromModule not in self._DynaPcdList_:
                continue
            Index = self._DynaPcdList_.index(PcdFromModule)
            if PcdFromModule.IsFromDsc == False and \
                PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE and \
                PcdFromModule.IsFromBinaryInf == True and \
                self._DynaPcdList_[Index].IsFromBinaryInf == False:
                Index = self._DynaPcdList_.index(PcdFromModule)
                self._DynaPcdList_.remove (self._DynaPcdList_[Index])

        # print out error information and break the build, if error found
        if len(NoDatumTypePcdList) > 0:
            NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)
            EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",
                            File=self.MetaFile,
                            ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
                                      % NoDatumTypePcdListString)
        self._NonDynamicPcdList = self._NonDynaPcdList_
        self._DynamicPcdList = self._DynaPcdList_
        #
        # Sort dynamic PCD list to:
        # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should 
        #    try to be put header of dynamicd List
        # 2) If PCD is HII type, the PCD item should be put after unicode type PCD
        #
        # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.
        #
        UnicodePcdArray = []
        HiiPcdArray     = []
        OtherPcdArray   = []
        VpdPcdDict      = {}
        VpdFile               = VpdInfoFile.VpdInfoFile()
        NeedProcessVpdMapFile = False

        for pcd in self.Platform.Pcds.keys():
            if pcd not in self._PlatformPcds.keys():
                self._PlatformPcds[pcd] = self.Platform.Pcds[pcd]
        
        for item in self._PlatformPcds:
            if self._PlatformPcds[item].DatumType and self._PlatformPcds[item].DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
                self._PlatformPcds[item].DatumType = "VOID*"

        if (self.Workspace.ArchList[-1] == self.Arch): 
            for Pcd in self._DynamicPcdList:
                # just pick the a value to determine whether is unicode string type
                Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]
                Sku.VpdOffset = Sku.VpdOffset.strip()
                
                if Pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
                    Pcd.DatumType = "VOID*"

                PcdValue = Sku.DefaultValue
                if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):
                    # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
                    UnicodePcdArray.append(Pcd)
                elif len(Sku.VariableName) > 0:
                    # if found HII type PCD then insert to right of UnicodeIndex
                    HiiPcdArray.append(Pcd)
                else:
                    OtherPcdArray.append(Pcd)
                if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:
                    VpdPcdDict[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] = Pcd
            
            #Collect DynamicHii PCD values and assign it to DynamicExVpd PCD gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer        
            PcdNvStoreDfBuffer = VpdPcdDict.get(("PcdNvStoreDefaultValueBuffer","gEfiMdeModulePkgTokenSpaceGuid"))
            if PcdNvStoreDfBuffer:
                var_info = self.CollectVariables(self._DynamicPcdList)
                default_skuobj = PcdNvStoreDfBuffer.SkuInfoList.get("DEFAULT")
                default_skuobj.DefaultValue = var_info.dump()
                PcdNvStoreDfBuffer.DefaultValue = var_info.dump()
                if default_skuobj:
                    PcdNvStoreDfBuffer.SkuInfoList.clear()
                    PcdNvStoreDfBuffer.SkuInfoList['DEFAULT'] = default_skuobj
                    PcdNvStoreDfBuffer.MaxDatumSize = str(len(default_skuobj.DefaultValue.split(",")))
            
            PlatformPcds = self._PlatformPcds.keys()
            PlatformPcds.sort()
            #
            # Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up.
            #
            for PcdKey in PlatformPcds:
                Pcd = self._PlatformPcds[PcdKey]
                if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD] and \
                   PcdKey in VpdPcdDict:
                    Pcd = VpdPcdDict[PcdKey]
                    for (SkuName,Sku) in Pcd.SkuInfoList.items():
                        Sku.VpdOffset = Sku.VpdOffset.strip()
                        PcdValue = Sku.DefaultValue
                        if PcdValue == "":
                            PcdValue  = Pcd.DefaultValue
                        if Sku.VpdOffset != '*':
                            if PcdValue.startswith("{"):
                                Alignment = 8
                            elif PcdValue.startswith("L"):
                                Alignment = 2
                            else:
                                Alignment = 1
                            try:
                                VpdOffset = int(Sku.VpdOffset)
                            except:
                                try:
                                    VpdOffset = int(Sku.VpdOffset, 16)
                                except:
                                    EdkLogger.error("build", FORMAT_INVALID, "Invalid offset value %s for PCD %s.%s." % (Sku.VpdOffset, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
                            if VpdOffset % Alignment != 0:
                                if PcdValue.startswith("{"):
                                    EdkLogger.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName), File=self.MetaFile)
                                else:
                                    EdkLogger.error("build", FORMAT_INVALID, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Alignment))
                        VpdFile.Add(Pcd, Sku.VpdOffset)
                        # if the offset of a VPD is *, then it need to be fixed up by third party tool.
                        if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":
                            NeedProcessVpdMapFile = True
                            if self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == '':
                                EdkLogger.error("Build", FILE_NOT_FOUND, \
                                                "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")


            #
            # Fix the PCDs define in VPD PCD section that never referenced by module.
            # An example is PCD for signature usage.
            #            
            for DscPcd in PlatformPcds:
                DscPcdEntry = self._PlatformPcds[DscPcd]
                if DscPcdEntry.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:
                    if not (self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == ''):
                        FoundFlag = False
                        for VpdPcd in VpdFile._VpdArray.keys():
                            # This PCD has been referenced by module
                            if (VpdPcd.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \
                               (VpdPcd.TokenCName == DscPcdEntry.TokenCName):
                                    FoundFlag = True

                        # Not found, it should be signature
                        if not FoundFlag :
                            # just pick the a value to determine whether is unicode string type
                            for (SkuName,Sku) in DscPcdEntry.SkuInfoList.items():
                                Sku.VpdOffset = Sku.VpdOffset.strip() 
                                
                                # Need to iterate DEC pcd information to get the value & datumtype
                                for eachDec in self.PackageList:
                                    for DecPcd in eachDec.Pcds:
                                        DecPcdEntry = eachDec.Pcds[DecPcd]
                                        if (DecPcdEntry.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \
                                           (DecPcdEntry.TokenCName == DscPcdEntry.TokenCName):
                                            # Print warning message to let the developer make a determine.
                                            EdkLogger.warn("build", "Unreferenced vpd pcd used!",
                                                            File=self.MetaFile, \
                                                            ExtraData = "PCD: %s.%s used in the DSC file %s is unreferenced." \
                                                            %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, self.Platform.MetaFile.Path))  
                                                                                  
                                            DscPcdEntry.DatumType    = DecPcdEntry.DatumType
                                            DscPcdEntry.DefaultValue = DecPcdEntry.DefaultValue
                                            DscPcdEntry.TokenValue = DecPcdEntry.TokenValue
                                            DscPcdEntry.TokenSpaceGuidValue = eachDec.Guids[DecPcdEntry.TokenSpaceGuidCName]
                                            # Only fix the value while no value provided in DSC file.
                                            if (Sku.DefaultValue == "" or Sku.DefaultValue==None):
                                                DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]].DefaultValue = DecPcdEntry.DefaultValue
                                                                                                                    
                                if DscPcdEntry not in self._DynamicPcdList:
                                    self._DynamicPcdList.append(DscPcdEntry)
#                                Sku = DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]]
                                Sku.VpdOffset = Sku.VpdOffset.strip()
                                PcdValue = Sku.DefaultValue
                                if PcdValue == "":
                                    PcdValue  = DscPcdEntry.DefaultValue
                                if Sku.VpdOffset != '*':
                                    if PcdValue.startswith("{"):
                                        Alignment = 8
                                    elif PcdValue.startswith("L"):
                                        Alignment = 2
                                    else:
                                        Alignment = 1
                                    try:
                                        VpdOffset = int(Sku.VpdOffset)
                                    except:
                                        try:
                                            VpdOffset = int(Sku.VpdOffset, 16)
                                        except:
                                            EdkLogger.error("build", FORMAT_INVALID, "Invalid offset value %s for PCD %s.%s." % (Sku.VpdOffset, DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName))
                                    if VpdOffset % Alignment != 0:
                                        if PcdValue.startswith("{"):
                                            EdkLogger.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName), File=self.MetaFile)
                                        else:
                                            EdkLogger.error("build", FORMAT_INVALID, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, Alignment))
                                VpdFile.Add(DscPcdEntry, Sku.VpdOffset)
                                if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":
                                    NeedProcessVpdMapFile = True 
                            if DscPcdEntry.DatumType == 'VOID*' and PcdValue.startswith("L"):
                                UnicodePcdArray.append(DscPcdEntry)
                            elif len(Sku.VariableName) > 0:
                                HiiPcdArray.append(DscPcdEntry)
                            else:
                                OtherPcdArray.append(DscPcdEntry)
                                
                                # if the offset of a VPD is *, then it need to be fixed up by third party tool.
                                                       
                    
                    
            if (self.Platform.FlashDefinition == None or self.Platform.FlashDefinition == '') and \
               VpdFile.GetCount() != 0:
                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, 
                                "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self.Platform.MetaFile))

            if VpdFile.GetCount() != 0:
                FvPath = os.path.join(self.BuildDir, "FV")
                if not os.path.exists(FvPath):
                    try:
                        os.makedirs(FvPath)
                    except:
                        EdkLogger.error("build", FILE_WRITE_FAILURE, "Fail to create FV folder under %s" % self.BuildDir)

                VpdFilePath = os.path.join(FvPath, "%s.txt" % self.Platform.VpdToolGuid)

                if VpdFile.Write(VpdFilePath):
                    # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file.
                    BPDGToolName = None
                    for ToolDef in self.ToolDefinition.values():
                        if ToolDef.has_key("GUID") and ToolDef["GUID"] == self.Platform.VpdToolGuid:
                            if not ToolDef.has_key("PATH"):
                                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self.Platform.VpdToolGuid)
                            BPDGToolName = ToolDef["PATH"]
                            break
                    # Call third party GUID BPDG tool.
                    if BPDGToolName != None:
                        VpdInfoFile.CallExtenalBPDGTool(BPDGToolName, VpdFilePath)
                    else:
                        EdkLogger.error("Build", FILE_NOT_FOUND, "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")

                # Process VPD map file generated by third party BPDG tool
                if NeedProcessVpdMapFile:
                    VpdMapFilePath = os.path.join(self.BuildDir, "FV", "%s.map" % self.Platform.VpdToolGuid)
                    if os.path.exists(VpdMapFilePath):
                        VpdFile.Read(VpdMapFilePath)

                        # Fixup "*" offset
                        for Pcd in self._DynamicPcdList:
                            # just pick the a value to determine whether is unicode string type
                            i = 0
                            for (SkuName,Sku) in Pcd.SkuInfoList.items():                        
                                if Sku.VpdOffset == "*":
                                    Sku.VpdOffset = VpdFile.GetOffset(Pcd)[i].strip()
                                i += 1
                    else:
                        EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath)

            # Delete the DynamicPcdList At the last time enter into this function 
            del self._DynamicPcdList[:]
        self._DynamicPcdList.extend(UnicodePcdArray)
        self._DynamicPcdList.extend(HiiPcdArray)
        self._DynamicPcdList.extend(OtherPcdArray)
        allskuset = [(SkuName,Sku.SkuId) for pcd in self._DynamicPcdList for (SkuName,Sku) in pcd.SkuInfoList.items()]
        for pcd in self._DynamicPcdList:
            if len(pcd.SkuInfoList) == 1:
                for (SkuName,SkuId) in allskuset:
                    if type(SkuId) in (str,unicode) and eval(SkuId) == 0 or SkuId == 0:
                        continue
                    pcd.SkuInfoList[SkuName] = pcd.SkuInfoList['DEFAULT']
        self.AllPcdList = self._NonDynamicPcdList + self._DynamicPcdList
        
    ## Return the platform build data object
    def _GetPlatform(self):
        if self._Platform == None:
            self._Platform = self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]
        return self._Platform

    ## Return platform name
    def _GetName(self):
        return self.Platform.PlatformName

    ## Return the meta file GUID
    def _GetGuid(self):
        return self.Platform.Guid

    ## Return the platform version
    def _GetVersion(self):
        return self.Platform.Version

    ## Return the FDF file name
    def _GetFdfFile(self):
        if self._FdfFile == None:
            if self.Workspace.FdfFile != "":
                self._FdfFile= mws.join(self.WorkspaceDir, self.Workspace.FdfFile)
            else:
                self._FdfFile = ''
        return self._FdfFile

    ## Return the build output directory platform specifies
    def _GetOutputDir(self):
        return self.Platform.OutputDirectory

    ## Return the directory to store all intermediate and final files built
    def _GetBuildDir(self):
        if self._BuildDir == None:
            if os.path.isabs(self.OutputDir):
                self._BuildDir = path.join(
                                            path.abspath(self.OutputDir),
                                            self.BuildTarget + "_" + self.ToolChain,
                                            )
            else:
                self._BuildDir = path.join(
                                            self.WorkspaceDir,
                                            self.OutputDir,
                                            self.BuildTarget + "_" + self.ToolChain,
                                            )
        return self._BuildDir

    ## Return directory of platform makefile
    #
    #   @retval     string  Makefile directory
    #
    def _GetMakeFileDir(self):
        if self._MakeFileDir == None:
            self._MakeFileDir = path.join(self.BuildDir, self.Arch)
        return self._MakeFileDir

    ## Return build command string
    #
    #   @retval     string  Build command string
    #
    def _GetBuildCommand(self):
        if self._BuildCommand == None:
            self._BuildCommand = []
            if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:
                self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"])
                if "FLAGS" in self.ToolDefinition["MAKE"]:
                    NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip()
                    if NewOption != '':
                        self._BuildCommand += SplitOption(NewOption)
        return self._BuildCommand

    ## Get tool chain definition
    #
    #  Get each tool defition for given tool chain from tools_def.txt and platform
    #
    def _GetToolDefinition(self):
        if self._ToolDefinitions == None:
            ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary
            if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase:
                EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration",
                                ExtraData="[%s]" % self.MetaFile)
            self._ToolDefinitions = {}
            DllPathList = set()
            for Def in ToolDefinition:
                Target, Tag, Arch, Tool, Attr = Def.split("_")
                if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:
                    continue

                Value = ToolDefinition[Def]
                # don't record the DLL
                if Attr == "DLL":
                    DllPathList.add(Value)
                    continue

                if Tool not in self._ToolDefinitions:
                    self._ToolDefinitions[Tool] = {}
                self._ToolDefinitions[Tool][Attr] = Value

            ToolsDef = ''
            MakePath = ''
            if GlobalData.gOptions.SilentMode and "MAKE" in self._ToolDefinitions:
                if "FLAGS" not in self._ToolDefinitions["MAKE"]:
                    self._ToolDefinitions["MAKE"]["FLAGS"] = ""
                self._ToolDefinitions["MAKE"]["FLAGS"] += " -s"
            MakeFlags = ''
            for Tool in self._ToolDefinitions:
                for Attr in self._ToolDefinitions[Tool]:
                    Value = self._ToolDefinitions[Tool][Attr]
                    if Tool in self.BuildOption and Attr in self.BuildOption[Tool]:
                        # check if override is indicated
                        if self.BuildOption[Tool][Attr].startswith('='):
                            Value = self.BuildOption[Tool][Attr][1:]
                        else:
                            if Attr != 'PATH':
                                Value += " " + self.BuildOption[Tool][Attr]
                            else:
                                Value = self.BuildOption[Tool][Attr]

                    if Attr == "PATH":
                        # Don't put MAKE definition in the file
                        if Tool == "MAKE":
                            MakePath = Value
                        else:
                            ToolsDef += "%s = %s\n" % (Tool, Value)
                    elif Attr != "DLL":
                        # Don't put MAKE definition in the file
                        if Tool == "MAKE":
                            if Attr == "FLAGS":
                                MakeFlags = Value
                        else:
                            ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)
                ToolsDef += "\n"

            SaveFileOnChange(self.ToolDefinitionFile, ToolsDef)
            for DllPath in DllPathList:
                os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"]
            os.environ["MAKE_FLAGS"] = MakeFlags

        return self._ToolDefinitions

    ## Return the paths of tools
    def _GetToolDefFile(self):
        if self._ToolDefFile == None:
            self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch)
        return self._ToolDefFile

    ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.
    def _GetToolChainFamily(self):
        if self._ToolChainFamily == None:
            ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase
            if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
               or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
               or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]:
                EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
                                   % self.ToolChain)
                self._ToolChainFamily = "MSFT"
            else:
                self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]
        return self._ToolChainFamily

    def _GetBuildRuleFamily(self):
        if self._BuildRuleFamily == None:
            ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase
            if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \
               or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \
               or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]:
                EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
                                   % self.ToolChain)
                self._BuildRuleFamily = "MSFT"
            else:
                self._BuildRuleFamily = ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]
        return self._BuildRuleFamily

    ## Return the build options specific for all modules in this platform
    def _GetBuildOptions(self):
        if self._BuildOption == None:
            self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)
        return self._BuildOption

    ## Return the build options specific for EDK modules in this platform
    def _GetEdkBuildOptions(self):
        if self._EdkBuildOption == None:
            self._EdkBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDK_NAME)
        return self._EdkBuildOption

    ## Return the build options specific for EDKII modules in this platform
    def _GetEdkIIBuildOptions(self):
        if self._EdkIIBuildOption == None:
            self._EdkIIBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDKII_NAME)
        return self._EdkIIBuildOption

    ## Parse build_rule.txt in Conf Directory.
    #
    #   @retval     BuildRule object
    #
    def _GetBuildRule(self):
        if self._BuildRule == None:
            BuildRuleFile = None
            if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary:
                BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]
            if BuildRuleFile in [None, '']:
                BuildRuleFile = gDefaultBuildRuleFile
            self._BuildRule = BuildRule(BuildRuleFile)
            if self._BuildRule._FileVersion == "":
                self._BuildRule._FileVersion = AutoGenReqBuildRuleVerNum
            else:
                if self._BuildRule._FileVersion < AutoGenReqBuildRuleVerNum :
                    # If Build Rule's version is less than the version number required by the tools, halting the build.
                    EdkLogger.error("build", AUTOGEN_ERROR,
                                    ExtraData="The version number [%s] of build_rule.txt is less than the version number required by the AutoGen.(the minimum required version number is [%s])"\
                                     % (self._BuildRule._FileVersion, AutoGenReqBuildRuleVerNum))

        return self._BuildRule

    ## Summarize the packages used by modules in this platform
    def _GetPackageList(self):
        if self._PackageList == None:
            self._PackageList = set()
            for La in self.LibraryAutoGenList:
                self._PackageList.update(La.DependentPackageList)
            for Ma in self.ModuleAutoGenList:
                self._PackageList.update(Ma.DependentPackageList)
            #Collect package set information from INF of FDF
            PkgSet = set()
            for ModuleFile in self._AsBuildModuleList:
                if ModuleFile in self.Platform.Modules:
                    continue
                ModuleData = self.BuildDatabase[ModuleFile, self.Arch, self.BuildTarget, self.ToolChain]
                PkgSet.update(ModuleData.Packages)
            self._PackageList = list(self._PackageList) + list (PkgSet)
        return self._PackageList

    def _GetNonDynamicPcdDict(self):
        if self._NonDynamicPcdDict:
            return self._NonDynamicPcdDict
        for Pcd in self.NonDynamicPcdList:
            self._NonDynamicPcdDict[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)] = Pcd
        return self._NonDynamicPcdDict

    ## Get list of non-dynamic PCDs
    def _GetNonDynamicPcdList(self):
        if self._NonDynamicPcdList == None:
            self.CollectPlatformDynamicPcds()
        return self._NonDynamicPcdList

    ## Get list of dynamic PCDs
    def _GetDynamicPcdList(self):
        if self._DynamicPcdList == None:
            self.CollectPlatformDynamicPcds()
        return self._DynamicPcdList

    ## Generate Token Number for all PCD
    def _GetPcdTokenNumbers(self):
        if self._PcdTokenNumber == None:
            self._PcdTokenNumber = sdict()
            TokenNumber = 1
            #
            # Make the Dynamic and DynamicEx PCD use within different TokenNumber area. 
            # Such as:
            # 
            # Dynamic PCD:
            # TokenNumber 0 ~ 10
            # DynamicEx PCD:
            # TokeNumber 11 ~ 20
            #
            for Pcd in self.DynamicPcdList:
                if Pcd.Phase == "PEI":
                    if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
                        EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
                        self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
                        TokenNumber += 1

            for Pcd in self.DynamicPcdList:
                if Pcd.Phase == "PEI":
                    if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
                        EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
                        self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
                        TokenNumber += 1

            for Pcd in self.DynamicPcdList:
                if Pcd.Phase == "DXE":
                    if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
                        EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
                        self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
                        TokenNumber += 1

            for Pcd in self.DynamicPcdList:
                if Pcd.Phase == "DXE":
                    if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
                        EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
                        self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
                        TokenNumber += 1

            for Pcd in self.NonDynamicPcdList:
                self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
                TokenNumber += 1
        return self._PcdTokenNumber

    ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform
    def _GetAutoGenObjectList(self):
        self._ModuleAutoGenList = []
        self._LibraryAutoGenList = []
        for ModuleFile in self.Platform.Modules:
            Ma = ModuleAutoGen(
                    self.Workspace,
                    ModuleFile,
                    self.BuildTarget,
                    self.ToolChain,
                    self.Arch,
                    self.MetaFile
                    )
            if Ma not in self._ModuleAutoGenList:
                self._ModuleAutoGenList.append(Ma)
            for La in Ma.LibraryAutoGenList:
                if La not in self._LibraryAutoGenList:
                    self._LibraryAutoGenList.append(La)
                if Ma not in La._ReferenceModules:
                    La._ReferenceModules.append(Ma)

    ## Summarize ModuleAutoGen objects of all modules to be built for this platform
    def _GetModuleAutoGenList(self):
        if self._ModuleAutoGenList == None:
            self._GetAutoGenObjectList()
        return self._ModuleAutoGenList

    ## Summarize ModuleAutoGen objects of all libraries to be built for this platform
    def _GetLibraryAutoGenList(self):
        if self._LibraryAutoGenList == None:
            self._GetAutoGenObjectList()
        return self._LibraryAutoGenList

    ## Test if a module is supported by the platform
    #
    #  An error will be raised directly if the module or its arch is not supported
    #  by the platform or current configuration
    #
    def ValidModule(self, Module):
        return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances \
            or Module in self._AsBuildModuleList

    ## Resolve the library classes in a module to library instances
    #
    # This method will not only resolve library classes but also sort the library
    # instances according to the dependency-ship.
    #
    #   @param  Module      The module from which the library classes will be resolved
    #
    #   @retval library_list    List of library instances sorted
    #
    def ApplyLibraryInstance(self, Module):
        # Cover the case that the binary INF file is list in the FDF file but not DSC file, return empty list directly
        if str(Module) not in self.Platform.Modules:
            return []

        ModuleType = Module.ModuleType

        # for overridding library instances with module specific setting
        PlatformModule = self.Platform.Modules[str(Module)]

        # add forced library instances (specified under LibraryClasses sections)
        #
        # If a module has a MODULE_TYPE of USER_DEFINED,
        # do not link in NULL library class instances from the global [LibraryClasses.*] sections.
        #
        if Module.ModuleType != SUP_MODULE_USER_DEFINED:
            for LibraryClass in self.Platform.LibraryClasses.GetKeys():
                if LibraryClass.startswith("NULL") and self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]:
                    Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]

        # add forced library instances (specified in module overrides)
        for LibraryClass in PlatformModule.LibraryClasses:
            if LibraryClass.startswith("NULL"):
                Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]

        # EdkII module
        LibraryConsumerList = [Module]
        Constructor         = []
        ConsumedByList      = sdict()
        LibraryInstance     = sdict()

        EdkLogger.verbose("")
        EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
        while len(LibraryConsumerList) > 0:
            M = LibraryConsumerList.pop()
            for LibraryClassName in M.LibraryClasses:
                if LibraryClassName not in LibraryInstance:
                    # override library instance for this module
                    if LibraryClassName in PlatformModule.LibraryClasses:
                        LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]
                    else:
                        LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]
                    if LibraryPath == None or LibraryPath == "":
                        LibraryPath = M.LibraryClasses[LibraryClassName]
                        if LibraryPath == None or LibraryPath == "":
                            EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
                                            "Instance of library class [%s] is not found" % LibraryClassName,
                                            File=self.MetaFile,
                                            ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))

                    LibraryModule = self.BuildDatabase[LibraryPath, self.Arch, self.BuildTarget, self.ToolChain]
                    # for those forced library instance (NULL library), add a fake library class
                    if LibraryClassName.startswith("NULL"):
                        LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))
                    elif LibraryModule.LibraryClass == None \
                         or len(LibraryModule.LibraryClass) == 0 \
                         or (ModuleType != 'USER_DEFINED'
                             and ModuleType not in LibraryModule.LibraryClass[0].SupModList):
                        # only USER_DEFINED can link against any library instance despite of its SupModList
                        EdkLogger.error("build", OPTION_MISSING,
                                        "Module type [%s] is not supported by library instance [%s]" \
                                        % (ModuleType, LibraryPath), File=self.MetaFile,
                                        ExtraData="consumed by [%s]" % str(Module))

                    LibraryInstance[LibraryClassName] = LibraryModule
                    LibraryConsumerList.append(LibraryModule)
                    EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))
                else:
                    LibraryModule = LibraryInstance[LibraryClassName]

                if LibraryModule == None:
                    continue

                if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:
                    Constructor.append(LibraryModule)

                if LibraryModule not in ConsumedByList:
                    ConsumedByList[LibraryModule] = []
                # don't add current module itself to consumer list
                if M != Module:
                    if M in ConsumedByList[LibraryModule]:
                        continue
                    ConsumedByList[LibraryModule].append(M)
        #
        # Initialize the sorted output list to the empty set
        #
        SortedLibraryList = []
        #
        # Q <- Set of all nodes with no incoming edges
        #
        LibraryList = [] #LibraryInstance.values()
        Q = []
        for LibraryClassName in LibraryInstance:
            M = LibraryInstance[LibraryClassName]
            LibraryList.append(M)
            if ConsumedByList[M] == []:
                Q.append(M)

        #
        # start the  DAG algorithm
        #
        while True:
            EdgeRemoved = True
            while Q == [] and EdgeRemoved:
                EdgeRemoved = False
                # for each node Item with a Constructor
                for Item in LibraryList:
                    if Item not in Constructor:
                        continue
                    # for each Node without a constructor with an edge e from Item to Node
                    for Node in ConsumedByList[Item]:
                        if Node in Constructor:
                            continue
                        # remove edge e from the graph if Node has no constructor
                        ConsumedByList[Item].remove(Node)
                        EdgeRemoved = True
                        if ConsumedByList[Item] == []:
                            # insert Item into Q
                            Q.insert(0, Item)
                            break
                    if Q != []:
                        break
            # DAG is done if there's no more incoming edge for all nodes
            if Q == []:
                break

            # remove node from Q
            Node = Q.pop()
            # output Node
            SortedLibraryList.append(Node)

            # for each node Item with an edge e from Node to Item do
            for Item in LibraryList:
                if Node not in ConsumedByList[Item]:
                    continue
                # remove edge e from the graph
                ConsumedByList[Item].remove(Node)

                if ConsumedByList[Item] != []:
                    continue
                # insert Item into Q, if Item has no other incoming edges
                Q.insert(0, Item)

        #
        # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
        #
        for Item in LibraryList:
            if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:
                ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])
                EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),
                                ExtraData=ErrorMessage, File=self.MetaFile)
            if Item not in SortedLibraryList:
                SortedLibraryList.append(Item)

        #
        # Build the list of constructor and destructir names
        # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
        #
        SortedLibraryList.reverse()
        return SortedLibraryList


    ## Override PCD setting (type, value, ...)
    #
    #   @param  ToPcd       The PCD to be overrided
    #   @param  FromPcd     The PCD overrideing from
    #
    def _OverridePcd(self, ToPcd, FromPcd, Module=""):
        #
        # in case there's PCDs coming from FDF file, which have no type given.
        # at this point, ToPcd.Type has the type found from dependent
        # package
        #
        TokenCName = ToPcd.TokenCName
        for PcdItem in GlobalData.MixedPcd:
            if (ToPcd.TokenCName, ToPcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
                TokenCName = PcdItem[0]
                break
        if FromPcd != None:
            if GlobalData.BuildOptionPcd:
                for pcd in GlobalData.BuildOptionPcd:
                    if (FromPcd.TokenSpaceGuidCName, FromPcd.TokenCName) == (pcd[0], pcd[1]):
                        FromPcd.DefaultValue = pcd[2]
                        break
            if ToPcd.Pending and FromPcd.Type not in [None, '']:
                ToPcd.Type = FromPcd.Type
            elif (ToPcd.Type not in [None, '']) and (FromPcd.Type not in [None, ''])\
                and (ToPcd.Type != FromPcd.Type) and (ToPcd.Type in FromPcd.Type):
                if ToPcd.Type.strip() == "DynamicEx":
                    ToPcd.Type = FromPcd.Type
            elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \
                and ToPcd.Type != FromPcd.Type:
                EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",
                                ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
                                          % (ToPcd.TokenSpaceGuidCName, TokenCName,
                                             ToPcd.Type, Module, FromPcd.Type),
                                          File=self.MetaFile)

            if FromPcd.MaxDatumSize not in [None, '']:
                ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
            if FromPcd.DefaultValue not in [None, '']:
                ToPcd.DefaultValue = FromPcd.DefaultValue
            if FromPcd.TokenValue not in [None, '']:
                ToPcd.TokenValue = FromPcd.TokenValue
            if FromPcd.MaxDatumSize not in [None, '']:
                ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
            if FromPcd.DatumType not in [None, '']:
                ToPcd.DatumType = FromPcd.DatumType
            if FromPcd.SkuInfoList not in [None, '', []]:
                ToPcd.SkuInfoList = FromPcd.SkuInfoList

            # check the validation of datum
            IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)
            if not IsValid:
                EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,
                                ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, TokenCName))
            ToPcd.validateranges = FromPcd.validateranges
            ToPcd.validlists = FromPcd.validlists
            ToPcd.expressions = FromPcd.expressions

        if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:
            EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \
                            % (ToPcd.TokenSpaceGuidCName, TokenCName))
            Value = ToPcd.DefaultValue
            if Value in [None, '']:
                ToPcd.MaxDatumSize = '1'
            elif Value[0] == 'L':
                ToPcd.MaxDatumSize = str((len(Value) - 2) * 2)
            elif Value[0] == '{':
                ToPcd.MaxDatumSize = str(len(Value.split(',')))
            else:
                ToPcd.MaxDatumSize = str(len(Value) - 1)

        # apply default SKU for dynamic PCDS if specified one is not available
        if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \
            and ToPcd.SkuInfoList in [None, {}, '']:
            if self.Platform.SkuName in self.Platform.SkuIds:
                SkuName = self.Platform.SkuName
            else:
                SkuName = 'DEFAULT'
            ToPcd.SkuInfoList = {
                SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName][0], '', '', '', '', '', ToPcd.DefaultValue)
            }

    ## Apply PCD setting defined platform to a module
    #
    #   @param  Module  The module from which the PCD setting will be overrided
    #
    #   @retval PCD_list    The list PCDs with settings from platform
    #
    def ApplyPcdSetting(self, Module, Pcds):
        # for each PCD in module
        for Name, Guid in Pcds:
            PcdInModule = Pcds[Name, Guid]
            # find out the PCD setting in platform
            if (Name, Guid) in self.Platform.Pcds:
                PcdInPlatform = self.Platform.Pcds[Name, Guid]
            else:
                PcdInPlatform = None
            # then override the settings if any
            self._OverridePcd(PcdInModule, PcdInPlatform, Module)
            # resolve the VariableGuid value
            for SkuId in PcdInModule.SkuInfoList:
                Sku = PcdInModule.SkuInfoList[SkuId]
                if Sku.VariableGuid == '': continue
                Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList, self.MetaFile.Path)
                if Sku.VariableGuidValue == None:
                    PackageList = "\n\t".join([str(P) for P in self.PackageList])
                    EdkLogger.error(
                                'build',
                                RESOURCE_NOT_AVAILABLE,
                                "Value of GUID [%s] is not found in" % Sku.VariableGuid,
                                ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \
                                                        % (Guid, Name, str(Module)),
                                File=self.MetaFile
                                )

        # override PCD settings with module specific setting
        if Module in self.Platform.Modules:
            PlatformModule = self.Platform.Modules[str(Module)]
            for Key  in PlatformModule.Pcds:
                if Key in Pcds:
                    self._OverridePcd(Pcds[Key], PlatformModule.Pcds[Key], Module)
        return Pcds.values()

    ## Resolve library names to library modules
    #
    # (for Edk.x modules)
    #
    #   @param  Module  The module from which the library names will be resolved
    #
    #   @retval library_list    The list of library modules
    #
    def ResolveLibraryReference(self, Module):
        EdkLogger.verbose("")
        EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
        LibraryConsumerList = [Module]

        # "CompilerStub" is a must for Edk modules
        if Module.Libraries:
            Module.Libraries.append("CompilerStub")
        LibraryList = []
        while len(LibraryConsumerList) > 0:
            M = LibraryConsumerList.pop()
            for LibraryName in M.Libraries:
                Library = self.Platform.LibraryClasses[LibraryName, ':dummy:']
                if Library == None:
                    for Key in self.Platform.LibraryClasses.data.keys():
                        if LibraryName.upper() == Key.upper():
                            Library = self.Platform.LibraryClasses[Key, ':dummy:']
                            break
                    if Library == None:
                        EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),
                            ExtraData="\t%s [%s]" % (str(Module), self.Arch))
                        continue

                if Library not in LibraryList:
                    LibraryList.append(Library)
                    LibraryConsumerList.append(Library)
                    EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library)))
        return LibraryList

    ## Calculate the priority value of the build option
    #
    # @param    Key    Build option definition contain: TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
    #
    # @retval   Value  Priority value based on the priority list.
    #
    def CalculatePriorityValue(self, Key):
        Target, ToolChain, Arch, CommandType, Attr = Key.split('_')
        PriorityValue = 0x11111
        if Target == "*":
            PriorityValue &= 0x01111
        if ToolChain == "*":
            PriorityValue &= 0x10111
        if Arch == "*":
            PriorityValue &= 0x11011
        if CommandType == "*":
            PriorityValue &= 0x11101
        if Attr == "*":
            PriorityValue &= 0x11110

        return self.PrioList["0x%0.5x" % PriorityValue]


    ## Expand * in build option key
    #
    #   @param  Options     Options to be expanded
    #
    #   @retval options     Options expanded
    #      
    def _ExpandBuildOption(self, Options, ModuleStyle=None):
        BuildOptions = {}
        FamilyMatch  = False
        FamilyIsNull = True

        OverrideList = {}
        #
        # Construct a list contain the build options which need override.
        #
        for Key in Options:
            #
            # Key[0] -- tool family
            # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
            #
            if (Key[0] == self.BuildRuleFamily and
                (ModuleStyle == None or len(Key) < 3 or (len(Key) > 2 and Key[2] == ModuleStyle))):
                Target, ToolChain, Arch, CommandType, Attr = Key[1].split('_')
                if Target == self.BuildTarget or Target == "*":
                    if ToolChain == self.ToolChain or ToolChain == "*":
                        if Arch == self.Arch or Arch == "*":
                            if Options[Key].startswith("="):
                                if OverrideList.get(Key[1]) != None:
                                    OverrideList.pop(Key[1])
                                OverrideList[Key[1]] = Options[Key]
        
        #
        # Use the highest priority value. 
        #
        if (len(OverrideList) >= 2):
            KeyList = OverrideList.keys()
            for Index in range(len(KeyList)):
                NowKey = KeyList[Index]
                Target1, ToolChain1, Arch1, CommandType1, Attr1 = NowKey.split("_")
                for Index1 in range(len(KeyList) - Index - 1):
                    NextKey = KeyList[Index1 + Index + 1]
                    #
                    # Compare two Key, if one is included by another, choose the higher priority one
                    #                    
                    Target2, ToolChain2, Arch2, CommandType2, Attr2 = NextKey.split("_")
                    if Target1 == Target2 or Target1 == "*" or Target2 == "*":
                        if ToolChain1 == ToolChain2 or ToolChain1 == "*" or ToolChain2 == "*":
                            if Arch1 == Arch2 or Arch1 == "*" or Arch2 == "*":
                                if CommandType1 == CommandType2 or CommandType1 == "*" or CommandType2 == "*":
                                    if Attr1 == Attr2 or Attr1 == "*" or Attr2 == "*":
                                        if self.CalculatePriorityValue(NowKey) > self.CalculatePriorityValue(NextKey):
                                            if Options.get((self.BuildRuleFamily, NextKey)) != None:
                                                Options.pop((self.BuildRuleFamily, NextKey))
                                        else:
                                            if Options.get((self.BuildRuleFamily, NowKey)) != None:
                                                Options.pop((self.BuildRuleFamily, NowKey))
                                                           
        for Key in Options:
            if ModuleStyle != None and len (Key) > 2:
                # Check Module style is EDK or EDKII.
                # Only append build option for the matched style module.
                if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:
                    continue
                elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:
                    continue
            Family = Key[0]
            Target, Tag, Arch, Tool, Attr = Key[1].split("_")
            # if tool chain family doesn't match, skip it
            if Tool in self.ToolDefinition and Family != "":
                FamilyIsNull = False
                if self.ToolDefinition[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
                    if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
                        continue
                elif Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
                    continue
                FamilyMatch = True
            # expand any wildcard
            if Target == "*" or Target == self.BuildTarget:
                if Tag == "*" or Tag == self.ToolChain:
                    if Arch == "*" or Arch == self.Arch:
                        if Tool not in BuildOptions:
                            BuildOptions[Tool] = {}
                        if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):
                            BuildOptions[Tool][Attr] = Options[Key]
                        else:
                            # append options for the same tool except PATH
                            if Attr != 'PATH':
                                BuildOptions[Tool][Attr] += " " + Options[Key]
                            else:
                                BuildOptions[Tool][Attr] = Options[Key]
        # Build Option Family has been checked, which need't to be checked again for family.
        if FamilyMatch or FamilyIsNull:
            return BuildOptions

        for Key in Options:
            if ModuleStyle != None and len (Key) > 2:
                # Check Module style is EDK or EDKII.
                # Only append build option for the matched style module.
                if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:
                    continue
                elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:
                    continue
            Family = Key[0]
            Target, Tag, Arch, Tool, Attr = Key[1].split("_")
            # if tool chain family doesn't match, skip it
            if Tool not in self.ToolDefinition or Family == "":
                continue
            # option has been added before
            if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
                continue

            # expand any wildcard
            if Target == "*" or Target == self.BuildTarget:
                if Tag == "*" or Tag == self.ToolChain:
                    if Arch == "*" or Arch == self.Arch:
                        if Tool not in BuildOptions:
                            BuildOptions[Tool] = {}
                        if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):
                            BuildOptions[Tool][Attr] = Options[Key]
                        else:
                            # append options for the same tool except PATH
                            if Attr != 'PATH':
                                BuildOptions[Tool][Attr] += " " + Options[Key]
                            else:
                                BuildOptions[Tool][Attr] = Options[Key]
        return BuildOptions

    ## Append build options in platform to a module
    #
    #   @param  Module  The module to which the build options will be appened
    #
    #   @retval options     The options appended with build options in platform
    #
    def ApplyBuildOption(self, Module):
        # Get the different options for the different style module
        if Module.AutoGenVersion < 0x00010005:
            PlatformOptions = self.EdkBuildOption
            ModuleTypeOptions = self.Platform.GetBuildOptionsByModuleType(EDK_NAME, Module.ModuleType)
        else:
            PlatformOptions = self.EdkIIBuildOption
            ModuleTypeOptions = self.Platform.GetBuildOptionsByModuleType(EDKII_NAME, Module.ModuleType)
        ModuleTypeOptions = self._ExpandBuildOption(ModuleTypeOptions)
        ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)
        if Module in self.Platform.Modules:
            PlatformModule = self.Platform.Modules[str(Module)]
            PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)
        else:
            PlatformModuleOptions = {}

        BuildRuleOrder = None
        for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:
            for Tool in Options:
                for Attr in Options[Tool]:
                    if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:
                        BuildRuleOrder = Options[Tool][Attr]

        AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() +
                       PlatformModuleOptions.keys() + ModuleTypeOptions.keys() +
                       self.ToolDefinition.keys())
        BuildOptions = {}
        for Tool in AllTools:
            if Tool not in BuildOptions:
                BuildOptions[Tool] = {}

            for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:
                if Tool not in Options:
                    continue
                for Attr in Options[Tool]:
                    Value = Options[Tool][Attr]
                    #
                    # Do not generate it in Makefile
                    #
                    if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:
                        continue
                    if Attr not in BuildOptions[Tool]:
                        BuildOptions[Tool][Attr] = ""
                    # check if override is indicated
                    if Value.startswith('='):
                        ToolPath = Value[1:]
                        ToolPath = mws.handleWsMacro(ToolPath)
                        BuildOptions[Tool][Attr] = ToolPath
                    else:
                        Value = mws.handleWsMacro(Value)
                        if Attr != 'PATH':
                            BuildOptions[Tool][Attr] += " " + Value
                        else:
                            BuildOptions[Tool][Attr] = Value
        if Module.AutoGenVersion < 0x00010005 and self.Workspace.UniFlag != None:
            #
            # Override UNI flag only for EDK module.
            #
            if 'BUILD' not in BuildOptions:
                BuildOptions['BUILD'] = {}
            BuildOptions['BUILD']['FLAGS'] = self.Workspace.UniFlag
        return BuildOptions, BuildRuleOrder

    Platform            = property(_GetPlatform)
    Name                = property(_GetName)
    Guid                = property(_GetGuid)
    Version             = property(_GetVersion)

    OutputDir           = property(_GetOutputDir)
    BuildDir            = property(_GetBuildDir)
    MakeFileDir         = property(_GetMakeFileDir)
    FdfFile             = property(_GetFdfFile)

    PcdTokenNumber      = property(_GetPcdTokenNumbers)    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
    DynamicPcdList      = property(_GetDynamicPcdList)    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
    NonDynamicPcdList   = property(_GetNonDynamicPcdList)    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
    NonDynamicPcdDict   = property(_GetNonDynamicPcdDict)
    PackageList         = property(_GetPackageList)

    ToolDefinition      = property(_GetToolDefinition)    # toolcode : tool path
    ToolDefinitionFile  = property(_GetToolDefFile)    # toolcode : lib path
    ToolChainFamily     = property(_GetToolChainFamily)
    BuildRuleFamily     = property(_GetBuildRuleFamily)
    BuildOption         = property(_GetBuildOptions)    # toolcode : option
    EdkBuildOption      = property(_GetEdkBuildOptions)   # edktoolcode : option
    EdkIIBuildOption    = property(_GetEdkIIBuildOptions) # edkiitoolcode : option

    BuildCommand        = property(_GetBuildCommand)
    BuildRule           = property(_GetBuildRule)
    ModuleAutoGenList   = property(_GetModuleAutoGenList)
    LibraryAutoGenList  = property(_GetLibraryAutoGenList)
    GenFdsCommand       = property(_GenFdsCommand)

## 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):
    ## Cache the timestamps of metafiles of every module in a class variable
    #
    TimeDict = {}

    ## The real constructor of ModuleAutoGen
    #
    #  This method is not supposed to be called by users of ModuleAutoGen. It's
    #  only used by factory method __new__() to do real initialization work for an
    #  object of 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 _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):
        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 = Workspace.WorkspaceDir

        self.MetaFile = ModuleFile
        self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)
        # check if this module is employed by active platform
        if not self.PlatformInfo.ValidModule(self.MetaFile):
            EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \
                              % (self.MetaFile, Arch))
            return False

        self.SourceDir = self.MetaFile.SubDir
        self.SourceDir = mws.relpath(self.SourceDir, self.WorkspaceDir)

        self.SourceOverrideDir = None
        # use overrided path defined in DSC file
        if self.MetaFile.Key in GlobalData.gOverrideDir:
            self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key]

        self.ToolChain = Toolchain
        self.BuildTarget = Target
        self.Arch = Arch
        self.ToolChainFamily = self.PlatformInfo.ToolChainFamily
        self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily

        self.IsMakeFileCreated = False
        self.IsCodeFileCreated = False
        self.IsAsBuiltInfCreated = False
        self.DepexGenerated = False

        self.BuildDatabase = self.Workspace.BuildDatabase
        self.BuildRuleOrder = None

        self._Module          = None
        self._Name            = None
        self._Guid            = None
        self._Version         = None
        self._ModuleType      = None
        self._ComponentType   = None
        self._PcdIsDriver     = None
        self._AutoGenVersion  = None
        self._LibraryFlag     = None
        self._CustomMakefile  = None
        self._Macro           = None

        self._BuildDir        = None
        self._OutputDir       = None
        self._DebugDir        = None
        self._MakeFileDir     = None

        self._IncludePathList = None
        self._IncludePathLength = 0
        self._AutoGenFileList = None
        self._UnicodeFileList = None
        self._VfrFileList = None
        self._IdfFileList = None
        self._SourceFileList  = None
        self._ObjectFileList  = None
        self._BinaryFileList  = None

        self._DependentPackageList    = None
        self._DependentLibraryList    = None
        self._LibraryAutoGenList      = None
        self._DerivedPackageList      = None
        self._ModulePcdList           = None
        self._LibraryPcdList          = None
        self._PcdComments = sdict()
        self._GuidList                = None
        self._GuidsUsedByPcd = None
        self._GuidComments = sdict()
        self._ProtocolList            = None
        self._ProtocolComments = sdict()
        self._PpiList                 = None
        self._PpiComments = sdict()
        self._DepexList               = None
        self._DepexExpressionList     = None
        self._BuildOption             = None
        self._BuildOptionIncPathList  = None
        self._BuildTargets            = None
        self._IntroBuildTargetList    = None
        self._FinalBuildTargetList    = None
        self._FileTypes               = None
        self._BuildRules              = None

        self._TimeStampPath           = None

        self.AutoGenDepSet = set()

        
        ## The Modules referenced to this Library
        #  Only Library has this attribute
        self._ReferenceModules        = []        
        
        ## Store the FixedAtBuild Pcds
        #  
        self._FixedAtBuildPcds         = []
        self.ConstPcd                  = {}
        return True

    def __repr__(self):
        return "%s [%s]" % (self.MetaFile, self.Arch)

    # Get FixedAtBuild Pcds of this Module
    def _GetFixedAtBuildPcds(self):
        if self._FixedAtBuildPcds:
            return self._FixedAtBuildPcds
        for Pcd in self.ModulePcdList:
            if Pcd.Type != "FixedAtBuild":
                continue
            if Pcd not in self._FixedAtBuildPcds:
                self._FixedAtBuildPcds.append(Pcd)
                
        return self._FixedAtBuildPcds        

    def _GetUniqueBaseName(self):
        BaseName = self.Name
        for Module in self.PlatformInfo.ModuleAutoGenList:
            if Module.MetaFile == self.MetaFile:
                continue
            if Module.Name == self.Name:
                if uuid.UUID(Module.Guid) == uuid.UUID(self.Guid):
                    EdkLogger.error("build", FILE_DUPLICATED, 'Modules have same BaseName and FILE_GUID:\n'
                                    '  %s\n  %s' % (Module.MetaFile, self.MetaFile))
                BaseName = '%s_%s' % (self.Name, self.Guid)
        return BaseName

    # Macros could be used in build_rule.txt (also Makefile)
    def _GetMacros(self):
        if self._Macro == None:
            self._Macro = sdict()
            self._Macro["WORKSPACE"             ] = self.WorkspaceDir
            self._Macro["MODULE_NAME"           ] = self.Name
            self._Macro["MODULE_NAME_GUID"      ] = self._GetUniqueBaseName()
            self._Macro["MODULE_GUID"           ] = self.Guid
            self._Macro["MODULE_VERSION"        ] = self.Version
            self._Macro["MODULE_TYPE"           ] = self.ModuleType
            self._Macro["MODULE_FILE"           ] = str(self.MetaFile)
            self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName
            self._Macro["MODULE_RELATIVE_DIR"   ] = self.SourceDir
            self._Macro["MODULE_DIR"            ] = self.SourceDir

            self._Macro["BASE_NAME"             ] = self.Name

            self._Macro["ARCH"                  ] = self.Arch
            self._Macro["TOOLCHAIN"             ] = self.ToolChain
            self._Macro["TOOLCHAIN_TAG"         ] = self.ToolChain
            self._Macro["TOOL_CHAIN_TAG"        ] = self.ToolChain
            self._Macro["TARGET"                ] = self.BuildTarget

            self._Macro["BUILD_DIR"             ] = self.PlatformInfo.BuildDir
            self._Macro["BIN_DIR"               ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)
            self._Macro["LIB_DIR"               ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)
            self._Macro["MODULE_BUILD_DIR"      ] = self.BuildDir
            self._Macro["OUTPUT_DIR"            ] = self.OutputDir
            self._Macro["DEBUG_DIR"             ] = self.DebugDir
            self._Macro["DEST_DIR_OUTPUT"       ] = self.OutputDir
            self._Macro["DEST_DIR_DEBUG"        ] = self.DebugDir
            self._Macro["PLATFORM_NAME"         ] = self.PlatformInfo.Name
            self._Macro["PLATFORM_GUID"         ] = self.PlatformInfo.Guid
            self._Macro["PLATFORM_VERSION"      ] = self.PlatformInfo.Version
            self._Macro["PLATFORM_RELATIVE_DIR" ] = self.PlatformInfo.SourceDir
            self._Macro["PLATFORM_DIR"          ] = mws.join(self.WorkspaceDir, self.PlatformInfo.SourceDir)
            self._Macro["PLATFORM_OUTPUT_DIR"   ] = self.PlatformInfo.OutputDir
        return self._Macro

    ## Return the module build data object
    def _GetModule(self):
        if self._Module == None:
            self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]
        return self._Module

    ## Return the module name
    def _GetBaseName(self):
        return self.Module.BaseName

    ## Return the module DxsFile if exist
    def _GetDxsFile(self):
        return self.Module.DxsFile

    ## Return the module SourceOverridePath
    def _GetSourceOverridePath(self):
        return self.Module.SourceOverridePath

    ## Return the module meta-file GUID
    def _GetGuid(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 realy 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
    def _GetVersion(self):
        return self.Module.Version

    ## Return the module type
    def _GetModuleType(self):
        return self.Module.ModuleType

    ## Return the component type (for Edk.x style of module)
    def _GetComponentType(self):
        return self.Module.ComponentType

    ## Return the build type
    def _GetBuildType(self):
        return self.Module.BuildType

    ## Return the PCD_IS_DRIVER setting
    def _GetPcdIsDriver(self):
        return self.Module.PcdIsDriver

    ## Return the autogen version, i.e. module meta-file version
    def _GetAutoGenVersion(self):
        return self.Module.AutoGenVersion

    ## Check if the module is library or not
    def _IsLibrary(self):
        if self._LibraryFlag == None:
            if self.Module.LibraryClass != None and self.Module.LibraryClass != []:
                self._LibraryFlag = True
            else:
                self._LibraryFlag = False
        return self._LibraryFlag

    ## Check if the module is binary module or not
    def _IsBinaryModule(self):
        return self.Module.IsBinaryModule

    ## Return the directory to store intermediate files of the module
    def _GetBuildDir(self):
        if self._BuildDir == None:
            self._BuildDir = path.join(
                                    self.PlatformInfo.BuildDir,
                                    self.Arch,
                                    self.SourceDir,
                                    self.MetaFile.BaseName
                                    )
            CreateDirectory(self._BuildDir)
        return self._BuildDir

    ## Return the directory to store the intermediate object files of the mdoule
    def _GetOutputDir(self):
        if self._OutputDir == None:
            self._OutputDir = path.join(self.BuildDir, "OUTPUT")
            CreateDirectory(self._OutputDir)
        return self._OutputDir

    ## Return the directory to store auto-gened source files of the mdoule
    def _GetDebugDir(self):
        if self._DebugDir == None:
            self._DebugDir = path.join(self.BuildDir, "DEBUG")
            CreateDirectory(self._DebugDir)
        return self._DebugDir

    ## Return the path of custom file
    def _GetCustomMakefile(self):
        if self._CustomMakefile == None:
            self._CustomMakefile = {}
            for Type in self.Module.CustomMakefile:
                if Type in gMakeTypeMap:
                    MakeType = gMakeTypeMap[Type]
                else:
                    MakeType = 'nmake'
                if self.SourceOverrideDir != None:
                    File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type])
                    if not os.path.exists(File):
                        File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
                else:
                    File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
                self._CustomMakefile[MakeType] = File
        return self._CustomMakefile

    ## Return the directory of the makefile
    #
    #   @retval     string  The directory string of module's makefile
    #
    def _GetMakeFileDir(self):
        return self.BuildDir

    ## Return build command string
    #
    #   @retval     string  Build command string
    #
    def _GetBuildCommand(self):
        return self.PlatformInfo.BuildCommand

    ## Get object list of all packages the module and its dependent libraries belong to
    #
    #   @retval     list    The list of package object
    #
    def _GetDerivedPackageList(self):
        PackageList = []
        for M in [self.Module] + 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 expresion.
    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)
            DepexExpresionList = InfObj.GetDepexExpresionList()
            for DepexExpresion in DepexExpresionList:
                for key in DepexExpresion.keys():
                    Arch, ModuleType = key
                    DepexExpr = [x for x in DepexExpresion[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:
                        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:
            for Depex in DepexList:
                for key in Depex.keys():
                    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
    #
    def _GetDepexTokenList(self):
        if self._DepexList == None:
            self._DepexList = {}
            if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
                return self._DepexList

            self._DepexList[self.ModuleType] = []

            for ModuleType in self._DepexList:
                DepexList = self._DepexList[ModuleType]
                #
                # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
                #
                for M in [self.Module] + self.DependentLibraryList:
                    Inherited = False
                    for D in M.Depex[self.Arch, ModuleType]:
                        if DepexList != []:
                            DepexList.append('AND')
                        DepexList.append('(')
                        DepexList.extend(D)
                        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.BaseName, DepexList))
                    if 'BEFORE' in DepexList or 'AFTER' in DepexList:
                        break
                if len(DepexList) > 0:
                    EdkLogger.verbose('')
        return self._DepexList

    ## Merge dependency expression
    #
    #   @retval     list    The token list of the dependency expression after parsed
    #
    def _GetDepexExpressionTokenList(self):
        if self._DepexExpressionList == None:
            self._DepexExpressionList = {}
            if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
                return self._DepexExpressionList

            self._DepexExpressionList[self.ModuleType] = ''

            for ModuleType in self._DepexExpressionList:
                DepexExpressionList = self._DepexExpressionList[ModuleType]
                #
                # 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, ModuleType]:
                        if DepexExpressionList != '':
                            DepexExpressionList += ' AND '
                        DepexExpressionList += '('
                        DepexExpressionList += D
                        DepexExpressionList = DepexExpressionList.rstrip('END').strip()
                        DepexExpressionList += ')'
                        Inherited = True
                    if Inherited:
                        EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexExpressionList))
                    if 'BEFORE' in DepexExpressionList or 'AFTER' in DepexExpressionList:
                        break
                if len(DepexExpressionList) > 0:
                    EdkLogger.verbose('')
                self._DepexExpressionList[ModuleType] = DepexExpressionList
        return self._DepexExpressionList

    ## Return the list of specification version required for the module
    #
    #   @retval     list    The list of specification defined in module file
    #
    def _GetSpecification(self):
        return self.Module.Specification

    ## Tool option for the module build
    #
    #   @param      PlatformInfo    The object of PlatformBuildInfo
    #   @retval     dict            The dict containing valid options
    #
    def _GetModuleBuildOption(self):
        if self._BuildOption == None:
            self._BuildOption, self.BuildRuleOrder = self.PlatformInfo.ApplyBuildOption(self.Module)
            if self.BuildRuleOrder:
                self.BuildRuleOrder = ['.%s' % Ext for Ext in self.BuildRuleOrder.split()]
        return self._BuildOption

    ## Get include path list from tool option for the module build
    #
    #   @retval     list            The include path list
    #
    def _GetBuildOptionIncPathList(self):
        if self._BuildOptionIncPathList == None:
            #
            # 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 ('MSFT'):
                gBuildOptIncludePattern = re.compile(r"(?:.*?)/I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)
            elif self.PlatformInfo.ToolChainFamily in ('INTEL', 'GCC', 'RVCT'):
                gBuildOptIncludePattern = re.compile(r"(?:.*?)-I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)
            else:
                #
                # New ToolChainFamily, don't known whether there is option to specify include directories
                #
                self._BuildOptionIncPathList = []
                return self._BuildOptionIncPathList
            
            BuildOptionIncPathList = []
            for Tool in ('CC', 'PP', 'VFRPP', 'ASLPP', 'ASLCC', 'APP', 'ASM'):
                Attr = 'FLAGS'
                try:
                    FlagOption = self.BuildOption[Tool][Attr]
                except KeyError:
                    FlagOption = ''
                
                if self.PlatformInfo.ToolChainFamily != 'RVCT':
                    IncPathList = [NormPath(Path, self.Macros) for Path in gBuildOptIncludePattern.findall(FlagOption)]
                else:
                    #
                    # RVCT may specify a list of directory seperated by commas
                    #
                    IncPathList = []
                    for Path in gBuildOptIncludePattern.findall(FlagOption):
                        PathList = GetSplitList(Path, TAB_COMMA_SPLIT)
                        IncPathList += [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 self.AutoGenVersion >= 0x00010005 and len(IncPathList) > 0:
                    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))

                
                BuildOptionIncPathList += IncPathList
            
            self._BuildOptionIncPathList = BuildOptionIncPathList
        
        return self._BuildOptionIncPathList
        
    ## 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.
    #
    def _GetSourceFileList(self):
        if self._SourceFileList == None:
            self._SourceFileList = []
            for F in self.Module.Sources:
                # match tool chain
                if F.TagName not in ("", "*", self.ToolChain):
                    EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, "
                                    "but [%s] is needed" % (F.TagName, str(F), self.ToolChain))
                    continue
                # match tool chain family
                if F.ToolChainFamily not in ("", "*", self.ToolChainFamily):
                    EdkLogger.debug(
                                EdkLogger.DEBUG_0,
                                "The file [%s] must be built by tools of [%s], " \
                                "but current toolchain family is [%s]" \
                                    % (str(F), F.ToolChainFamily, self.ToolChainFamily))
                    continue

                # add the file path into search path list for file including
                if F.Dir not in self.IncludePathList and self.AutoGenVersion >= 0x00010005:
                    self.IncludePathList.insert(0, F.Dir)
                self._SourceFileList.append(F)

            self._MatchBuildRuleOrder(self._SourceFileList)

            for F in self._SourceFileList:
                self._ApplyBuildRule(F, TAB_UNKNOWN_FILE)
        return self._SourceFileList

    def _MatchBuildRuleOrder(self, FileList):
        Order_Dict = {}
        self._GetModuleBuildOption()
        for SingleFile in FileList:
            if self.BuildRuleOrder and SingleFile.Ext in self.BuildRuleOrder and SingleFile.Ext in self.BuildRules:
                key = SingleFile.Path.split(SingleFile.Ext)[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
    def _GetUnicodeFileList(self):
        if self._UnicodeFileList == None:
            if TAB_UNICODE_FILE in self.FileTypes:
                self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE]
            else:
                self._UnicodeFileList = []
        return self._UnicodeFileList

    ## Return the list of vfr files
    def _GetVfrFileList(self):
        if self._VfrFileList == None:
            if TAB_VFR_FILE in self.FileTypes:
                self._VfrFileList = self.FileTypes[TAB_VFR_FILE]
            else:
                self._VfrFileList = []
        return self._VfrFileList

    ## Return the list of Image Definition files
    def _GetIdfFileList(self):
        if self._IdfFileList == None:
            if TAB_IMAGE_FILE in self.FileTypes:
                self._IdfFileList = self.FileTypes[TAB_IMAGE_FILE]
            else:
                self._IdfFileList = []
        return self._IdfFileList

    ## 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
    #
    def _GetBinaryFiles(self):
        if self._BinaryFileList == None:
            self._BinaryFileList = []
            for F in self.Module.Binaries:
                if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget:
                    continue
                self._BinaryFileList.append(F)
                self._ApplyBuildRule(F, F.Type)
        return self._BinaryFileList

    def _GetBuildRules(self):
        if self._BuildRules == None:
            BuildRules = {}
            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)
                BuildRules[Type] = RuleObject
                for Ext in RuleObject.SourceFileExtList:
                    BuildRules[Ext] = RuleObject
            self._BuildRules = BuildRules
        return self._BuildRules

    def _ApplyBuildRule(self, File, FileType):
        if self._BuildTargets == None:
            self._IntroBuildTargetList = set()
            self._FinalBuildTargetList = set()
            self._BuildTargets = {}
            self._FileTypes = {}

        SubDirectory = os.path.join(self.OutputDir, File.SubDir)
        if not os.path.exists(SubDirectory):
            CreateDirectory(SubDirectory)
        LastTarget = None
        RuleChain = []
        SourceList = [File]
        Index = 0
        #
        # Make sure to get build rule order value
        #
        self._GetModuleBuildOption()

        while Index < len(SourceList):
            Source = SourceList[Index]
            Index = Index + 1

            if Source != File:
                CreateDirectory(Source.Dir)

            if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._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:
                # stop at no more rules
                if LastTarget:
                    self._FinalBuildTargetList.add(LastTarget)
                break

            FileType = RuleObject.SourceFileType
            if FileType not in self._FileTypes:
                self._FileTypes[FileType] = set()
            self._FileTypes[FileType].add(Source)

            # stop at STATIC_LIBRARY for library
            if self.IsLibrary and FileType == TAB_STATIC_LIBRARY:
                if LastTarget:
                    self._FinalBuildTargetList.add(LastTarget)
                break

            Target = RuleObject.Apply(Source, self.BuildRuleOrder)
            if not Target:
                if LastTarget:
                    self._FinalBuildTargetList.add(LastTarget)
                break
            elif not Target.Outputs:
                # Only do build for target with outputs
                self._FinalBuildTargetList.add(Target)

            if FileType not in self._BuildTargets:
                self._BuildTargets[FileType] = set()
            self._BuildTargets[FileType].add(Target)

            if not Source.IsBinary and Source == File:
                self._IntroBuildTargetList.add(Target)

            # to avoid cyclic rule
            if FileType in RuleChain:
                break

            RuleChain.append(FileType)
            SourceList.extend(Target.Outputs)
            LastTarget = Target
            FileType = TAB_UNKNOWN_FILE

    def _GetTargets(self):
        if self._BuildTargets == None:
            self._IntroBuildTargetList = set()
            self._FinalBuildTargetList = set()
            self._BuildTargets = {}
            self._FileTypes = {}

        #TRICK: call _GetSourceFileList to apply build rule for source files
        if self.SourceFileList:
            pass

        #TRICK: call _GetBinaryFileList to apply build rule for binary files
        if self.BinaryFileList:
            pass

        return self._BuildTargets

    def _GetIntroTargetList(self):
        self._GetTargets()
        return self._IntroBuildTargetList

    def _GetFinalTargetList(self):
        self._GetTargets()
        return self._FinalBuildTargetList

    def _GetFileTypes(self):
        self._GetTargets()
        return self._FileTypes

    ## Get the list of package object the module depends on
    #
    #   @retval     list    The package object list
    #
    def _GetDependentPackageList(self):
        return self.Module.Packages

    ## Return the list of auto-generated code file
    #
    #   @retval     list        The list of auto-generated file
    #
    def _GetAutoGenFileList(self):
        UniStringAutoGenC = True
        IdfStringAutoGenC = True
        UniStringBinBuffer = StringIO()
        IdfGenBinBuffer = StringIO()
        if self.BuildType == 'UEFI_HII':
            UniStringAutoGenC = False
            IdfStringAutoGenC = False
        if self._AutoGenFileList == None:
            self._AutoGenFileList = {}
            AutoGenC = TemplateString()
            AutoGenH = TemplateString()
            StringH = TemplateString()
            StringIdf = TemplateString()
            GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer, StringIdf, IdfStringAutoGenC, 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)
                self._AutoGenFileList[AutoFile] = str(AutoGenC)
                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
            if str(AutoGenH) != "":
                AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir)
                self._AutoGenFileList[AutoFile] = str(AutoGenH)
                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
            if str(StringH) != "":
                AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir)
                self._AutoGenFileList[AutoFile] = str(StringH)
                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
            if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "":
                AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)
                self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue()
                AutoFile.IsBinary = True
                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
            if UniStringBinBuffer != None:
                UniStringBinBuffer.close()
            if str(StringIdf) != "":
                AutoFile = PathClass(gAutoGenImageDefFileName % {"module_name":self.Name}, self.DebugDir)
                self._AutoGenFileList[AutoFile] = str(StringIdf)
                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
            if IdfGenBinBuffer != None and IdfGenBinBuffer.getvalue() != "":
                AutoFile = PathClass(gAutoGenIdfFileName % {"module_name":self.Name}, self.OutputDir)
                self._AutoGenFileList[AutoFile] = IdfGenBinBuffer.getvalue()
                AutoFile.IsBinary = True
                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
            if IdfGenBinBuffer != None:
                IdfGenBinBuffer.close()
        return self._AutoGenFileList

    ## Return the list of library modules explicitly or implicityly used by this module
    def _GetLibraryList(self):
        if self._DependentLibraryList == None:
            # only merge library classes and PCD for non-library module
            if self.IsLibrary:
                self._DependentLibraryList = []
            else:
                if self.AutoGenVersion < 0x00010005:
                    self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module)
                else:
                    self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)
        return self._DependentLibraryList

    @staticmethod
    def UpdateComments(Recver, Src):
        for Key in Src:
            if Key not in Recver:
                Recver[Key] = []
            Recver[Key].extend(Src[Key])
    ## Get the list of PCDs from current module
    #
    #   @retval     list                    The list of PCD
    #
    def _GetModulePcdList(self):
        if self._ModulePcdList == None:
            # apply PCD settings from platform
            self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)
            self.UpdateComments(self._PcdComments, self.Module.PcdComments)
        return self._ModulePcdList

    ## Get the list of PCDs from dependent libraries
    #
    #   @retval     list                    The list of PCD
    #
    def _GetLibraryPcdList(self):
        if self._LibraryPcdList == None:
            Pcds = sdict()
            if not self.IsLibrary:
                # get PCDs from dependent libraries
                for Library in self.DependentLibraryList:
                    self.UpdateComments(self._PcdComments, Library.PcdComments)
                    for Key in Library.Pcds:
                        # skip duplicated PCDs
                        if Key in self.Module.Pcds or Key in Pcds:
                            continue
                        Pcds[Key] = copy.copy(Library.Pcds[Key])
                # apply PCD settings from platform
                self._LibraryPcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, Pcds)
            else:
                self._LibraryPcdList = []
        return self._LibraryPcdList

    ## Get the GUID value mapping
    #
    #   @retval     dict    The mapping between GUID cname and its value
    #
    def _GetGuidList(self):
        if self._GuidList == None:
            self._GuidList = sdict()
            self._GuidList.update(self.Module.Guids)
            for Library in self.DependentLibraryList:
                self._GuidList.update(Library.Guids)
                self.UpdateComments(self._GuidComments, Library.GuidComments)
            self.UpdateComments(self._GuidComments, self.Module.GuidComments)
        return self._GuidList

    def GetGuidsUsedByPcd(self):
        if self._GuidsUsedByPcd == None:
            self._GuidsUsedByPcd = sdict()
            self._GuidsUsedByPcd.update(self.Module.GetGuidsUsedByPcd())
            for Library in self.DependentLibraryList:
                self._GuidsUsedByPcd.update(Library.GetGuidsUsedByPcd())
        return self._GuidsUsedByPcd
    ## Get the protocol value mapping
    #
    #   @retval     dict    The mapping between protocol cname and its value
    #
    def _GetProtocolList(self):
        if self._ProtocolList == None:
            self._ProtocolList = sdict()
            self._ProtocolList.update(self.Module.Protocols)
            for Library in self.DependentLibraryList:
                self._ProtocolList.update(Library.Protocols)
                self.UpdateComments(self._ProtocolComments, Library.ProtocolComments)
            self.UpdateComments(self._ProtocolComments, self.Module.ProtocolComments)
        return self._ProtocolList

    ## Get the PPI value mapping
    #
    #   @retval     dict    The mapping between PPI cname and its value
    #
    def _GetPpiList(self):
        if self._PpiList == None:
            self._PpiList = sdict()
            self._PpiList.update(self.Module.Ppis)
            for Library in self.DependentLibraryList:
                self._PpiList.update(Library.Ppis)
                self.UpdateComments(self._PpiComments, Library.PpiComments)
            self.UpdateComments(self._PpiComments, self.Module.PpiComments)
        return self._PpiList

    ## Get the list of include search path
    #
    #   @retval     list                    The list path
    #
    def _GetIncludePathList(self):
        if self._IncludePathList == None:
            self._IncludePathList = []
            if self.AutoGenVersion < 0x00010005:
                for Inc in self.Module.Includes:
                    if Inc not in self._IncludePathList:
                        self._IncludePathList.append(Inc)
                    # for Edk modules
                    Inc = path.join(Inc, self.Arch.capitalize())
                    if os.path.exists(Inc) and Inc not in self._IncludePathList:
                        self._IncludePathList.append(Inc)
                # Edk module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
                self._IncludePathList.append(self.DebugDir)
            else:
                self._IncludePathList.append(self.MetaFile.Dir)
                self._IncludePathList.append(self.DebugDir)

            for Package in self.Module.Packages:
                PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir)
                if PackageDir not in self._IncludePathList:
                    self._IncludePathList.append(PackageDir)
                IncludesList = Package.Includes
                if Package._PrivateIncludes:
                    if not self.MetaFile.Path.startswith(PackageDir):
                        IncludesList = list(set(Package.Includes).difference(set(Package._PrivateIncludes)))
                for Inc in IncludesList:
                    if Inc not in self._IncludePathList:
                        self._IncludePathList.append(str(Inc))
        return self._IncludePathList

    def _GetIncludePathLength(self):
        self._IncludePathLength = 0
        if self._IncludePathList:
            for inc in self._IncludePathList:
                self._IncludePathLength += len(' ' + inc)
        return self._IncludePathLength

    ## 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 = []
        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.append((NameArray, GuidStructureStringToGuidString(Guid.group(1))))
                Pos = Content.find('efivarstore', Name.end())
        if not NameGuids:
            return []
        HiiExPcds = []
        for Pcd in self.PlatformInfo.Platform.Pcds.values():
            if Pcd.Type != TAB_PCDS_DYNAMIC_EX_HII:
                continue
            for SkuName in Pcd.SkuInfoList:
                SkuInfo = Pcd.SkuInfoList[SkuName]
                Name = ConvertStringToByteArray(SkuInfo.VariableName)
                Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList, self.MetaFile.Path)
                if not Value:
                    continue
                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")
            if 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 len(VfrUniBaseName) == 0:
            return None
        MapFileName = os.path.join(self.OutputDir, self.Name + ".map")
        EfiFileName = os.path.join(self.OutputDir, self.Name + ".efi")
        VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, 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 StringIO to cache data
        fStringIO = StringIO('')  

        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 = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
                UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]
                fStringIO.write(''.join(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 = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
                VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]
                fStringIO.write(''.join(VfrGuid))                   
                type (Item[1]) 
                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

    ## Create AsBuilt INF file the module
    #
    def CreateAsBuiltInf(self):
        if self.IsAsBuiltInfCreated:
            return
            
        # Skip the following code for EDK I inf
        if self.AutoGenVersion < 0x00010005:
            return
            
        # Skip the following code for libraries
        if self.IsLibrary:
            return
            
        # Skip the following code for modules with no source files
        if self.SourceFileList == None or self.SourceFileList == []:
            return

        # Skip the following code for modules without any binary files
        if self.BinaryFileList <> None and 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 += [Pcd]
                PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'PatchableInModule'))
            elif Pcd.Type in GenC.gDynamicExPcd:
                if Pcd not in Pcds:
                    Pcds += [Pcd]
                    PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'DynamicEx'))
                    PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'Dynamic'))
                    PcdTokenSpaceList.append(Pcd.TokenSpaceGuidCName)
        GuidList = sdict()
        GuidList.update(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 += [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, 'DynamicEx') in Pkg.Pcds or
                    (VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'Dynamic') in Pkg.Pcds):
                    Packages += [Pkg]
                    break

        ModuleType = self.ModuleType
        if ModuleType == 'UEFI_DRIVER' and self.DepexGenerated:
            ModuleType = 'DXE_DRIVER'

        DriverType = ''
        if self.PcdIsDriver != '':
            DriverType = self.PcdIsDriver

        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'                      : ['%s' % (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 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'] += [DriverType]

        if 'UEFI_SPECIFICATION_VERSION' in self.Specification:
            AsBuiltInfDict['module_uefi_specification_version'] += [self.Specification['UEFI_SPECIFICATION_VERSION']]
        if 'PI_SPECIFICATION_VERSION' in self.Specification:
            AsBuiltInfDict['module_pi_specification_version'] += [self.Specification['PI_SPECIFICATION_VERSION']]

        OutputDir = self.OutputDir.replace('\\', '/').strip('/')

        for Item in self.CodaTargetList:
            File = Item.Target.Path.replace('\\', '/').strip('/').replace(OutputDir, '').strip('/')
            if Item.Target.Ext.lower() == '.aml':
                AsBuiltInfDict['binary_item'] += ['ASL|' + File]
            elif Item.Target.Ext.lower() == '.acpi':
                AsBuiltInfDict['binary_item'] += ['ACPI|' + File]
            elif Item.Target.Ext.lower() == '.efi':
                AsBuiltInfDict['binary_item'] += ['PE32|' + self.Name + '.efi']
            else:
                AsBuiltInfDict['binary_item'] += ['BIN|' + File]
        if self.DepexGenerated:
            if self.ModuleType in ['PEIM']:
                AsBuiltInfDict['binary_item'] += ['PEI_DEPEX|' + self.Name + '.depex']
            if self.ModuleType in ['DXE_DRIVER', 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'UEFI_DRIVER']:
                AsBuiltInfDict['binary_item'] += ['DXE_DEPEX|' + self.Name + '.depex']
            if self.ModuleType in ['DXE_SMM_DRIVER']:
                AsBuiltInfDict['binary_item'] += ['SMM_DEPEX|' + self.Name + '.depex']

        Bin = self._GenOffsetBin()
        if Bin:
            AsBuiltInfDict['binary_item'] += ['BIN|%s' % Bin]

        for Root, Dirs, Files in os.walk(OutputDir):
            for File in Files:
                if File.lower().endswith('.pdb'):
                    AsBuiltInfDict['binary_item'] += ['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 = ''
                if CName in Item[1]:
                    Comments = '\n  '.join(Item[1][CName])
                Entry = CName
                if Comments:
                    Entry = Comments + '\n  ' + 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 ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
                    HexFormat = '0x%02x'
                    if Pcd.DatumType == 'UINT16':
                        HexFormat = '0x%04x'
                    elif Pcd.DatumType == 'UINT32':
                        HexFormat = '0x%08x'
                    elif Pcd.DatumType == 'UINT64':
                        HexFormat = '0x%016x'
                    PcdValue = HexFormat % int(Pcd.DefaultValue, 0)
                else:
                    if Pcd.MaxDatumSize == 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):
                            EdkLogger.error("build", AUTOGEN_ERROR,
                                            "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName)
                                            )
                        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:
                        EdkLogger.error("build", AUTOGEN_ERROR,
                                        "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName)
                                        )
                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)

        HiiPcds = []
        for Pcd in Pcds + VfrPcds:
            PcdComments = ''
            PcdCommentList = []
            HiiInfo = ''
            SkuId = ''
            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]
                    SkuId = SkuInfo.SkuId
                    HiiInfo = '## %s|%s|%s' % (SkuInfo.VariableName, SkuInfo.VariableGuid, SkuInfo.VariableOffset)
                    break
            if SkuId:
                #
                # Don't generate duplicated HII PCD
                #
                if (SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in HiiPcds:
                    continue
                else:
                    HiiPcds.append((SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
            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'] += [PcdEntry]
        for Item in self.BuildOption:
            if 'FLAGS' in self.BuildOption[Item]:
                AsBuiltInfDict['flags_item'] += ['%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'] += [Library.MetaFile.File.replace('\\', '/')]
        
        # Generated depex expression section in comments.
        AsBuiltInfDict['depexsection_item'] = ''
        DepexExpresion = self._GetDepexExpresionString()
        if DepexExpresion:
            AsBuiltInfDict['depexsection_item'] = DepexExpresion
        
        AsBuiltInf = TemplateString()
        AsBuiltInf.Append(gAsBuiltInfHeaderString.Replace(AsBuiltInfDict))
        
        SaveFileOnChange(os.path.join(self.OutputDir, self.Name + '.inf'), str(AsBuiltInf), False)
        
        self.IsAsBuiltInfCreated = True
        
    ## Create makefile for the module and its dependent libraries
    #
    #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of
    #                                       dependent libraries will be created
    #
    def CreateMakeFile(self, CreateLibraryMakeFile=True):
        # Ignore generating makefile when it is a binary module
        if self.IsBinaryModule:
            return

        if self.IsMakeFileCreated:
            return
        if self.CanSkip():
            return

        if not self.IsLibrary and CreateLibraryMakeFile:
            for LibraryAutoGen in self.LibraryAutoGenList:
                LibraryAutoGen.CreateMakeFile()

        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))

        self.CreateTimeStamp(Makefile)
        self.IsMakeFileCreated = True

    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
        if self.CanSkip():
            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()

        AutoGenList = []
        IgoredAutoGenList = []

        for File in self.AutoGenFileList:
            if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary):
                #Ignore Edk AutoGen.c
                if self.AutoGenVersion < 0x00010005 and File.Name == 'AutoGen.c':
                        continue

                AutoGenList.append(str(File))
            else:
                IgoredAutoGenList.append(str(File))

        # Skip the following code for EDK I inf
        if self.AutoGenVersion < 0x00010005:
            return

        for ModuleType in self.DepexList:
            # Ignore empty [depex] section or [depex] section for "USER_DEFINED" module
            if len(self.DepexList[ModuleType]) == 0 or ModuleType == "USER_DEFINED":
                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
    def _GetLibraryAutoGenList(self):
        if self._LibraryAutoGenList == None:
            self._LibraryAutoGenList = []
            for Library in self.DependentLibraryList:
                La = ModuleAutoGen(
                        self.Workspace,
                        Library.MetaFile,
                        self.BuildTarget,
                        self.ToolChain,
                        self.Arch,
                        self.PlatformInfo.MetaFile
                        )
                if La not in self._LibraryAutoGenList:
                    self._LibraryAutoGenList.append(La)
                    for Lib in La.CodaTargetList:
                        self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)
        return self._LibraryAutoGenList

    ## Decide whether we can skip the ModuleAutoGen process
    #  If any source file is newer than the modeule than we cannot skip
    #
    def CanSkip(self):
        if not os.path.exists(self.GetTimeStampPath()):
            return False
        #last creation time of the module
        DstTimeStamp = os.stat(self.GetTimeStampPath())[8]

        SrcTimeStamp = self.Workspace._SrcTimeStamp
        if SrcTimeStamp > DstTimeStamp:
            return False

        with open(self.GetTimeStampPath(),'r') as f:
            for source in f:
                source = source.rstrip('\n')
                if source not in ModuleAutoGen.TimeDict :
                    ModuleAutoGen.TimeDict[source] = os.stat(source)[8]
                if ModuleAutoGen.TimeDict[source] > DstTimeStamp:
                    return False
        return True

    def GetTimeStampPath(self):
        if self._TimeStampPath == None:
            self._TimeStampPath = os.path.join(self.MakeFileDir, 'AutoGenTimeStamp')
        return self._TimeStampPath
    def CreateTimeStamp(self, Makefile):

        FileSet = set()

        FileSet.add (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.GetTimeStampPath()):
            os.remove (self.GetTimeStampPath())
        with open(self.GetTimeStampPath(), 'w+') as file:
            for f in FileSet:
                print >> file, f

    Module          = property(_GetModule)
    Name            = property(_GetBaseName)
    Guid            = property(_GetGuid)
    Version         = property(_GetVersion)
    ModuleType      = property(_GetModuleType)
    ComponentType   = property(_GetComponentType)
    BuildType       = property(_GetBuildType)
    PcdIsDriver     = property(_GetPcdIsDriver)
    AutoGenVersion  = property(_GetAutoGenVersion)
    Macros          = property(_GetMacros)
    Specification   = property(_GetSpecification)

    IsLibrary       = property(_IsLibrary)
    IsBinaryModule  = property(_IsBinaryModule)
    BuildDir        = property(_GetBuildDir)
    OutputDir       = property(_GetOutputDir)
    DebugDir        = property(_GetDebugDir)
    MakeFileDir     = property(_GetMakeFileDir)
    CustomMakefile  = property(_GetCustomMakefile)

    IncludePathList = property(_GetIncludePathList)
    IncludePathLength = property(_GetIncludePathLength)
    AutoGenFileList = property(_GetAutoGenFileList)
    UnicodeFileList = property(_GetUnicodeFileList)
    VfrFileList     = property(_GetVfrFileList)
    SourceFileList  = property(_GetSourceFileList)
    BinaryFileList  = property(_GetBinaryFiles) # FileType : [File List]
    Targets         = property(_GetTargets)
    IntroTargetList = property(_GetIntroTargetList)
    CodaTargetList  = property(_GetFinalTargetList)
    FileTypes       = property(_GetFileTypes)
    BuildRules      = property(_GetBuildRules)
    IdfFileList     = property(_GetIdfFileList)

    DependentPackageList    = property(_GetDependentPackageList)
    DependentLibraryList    = property(_GetLibraryList)
    LibraryAutoGenList      = property(_GetLibraryAutoGenList)
    DerivedPackageList      = property(_GetDerivedPackageList)

    ModulePcdList           = property(_GetModulePcdList)
    LibraryPcdList          = property(_GetLibraryPcdList)
    GuidList                = property(_GetGuidList)
    ProtocolList            = property(_GetProtocolList)
    PpiList                 = property(_GetPpiList)
    DepexList               = property(_GetDepexTokenList)
    DxsFile                 = property(_GetDxsFile)
    DepexExpressionList     = property(_GetDepexExpressionTokenList)
    BuildOption             = property(_GetModuleBuildOption)
    BuildOptionIncPathList  = property(_GetBuildOptionIncPathList)
    BuildCommand            = property(_GetBuildCommand)
    
    FixedAtBuildPcds         = property(_GetFixedAtBuildPcds)

# This acts like the main() function for the script, unless it is 'import'ed into another script.
if __name__ == '__main__':
    pass

