Fixed a key error
authorjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Thu, 19 Jun 2008 02:32:10 +0000 (02:32 +0000)
committerjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Thu, 19 Jun 2008 02:32:10 +0000 (02:32 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1262 7335b38e-4728-0410-8992-fb3ffe349368

Source/Python/AutoGen/AutoGen.py

index 81369a8..a65e893 100755 (executable)
-## @file\r
-# Generate AutoGen.h, AutoGen.c and *.depex files\r
-#\r
-# Copyright (c) 2007, Intel Corporation\r
-# All rights reserved. This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution.  The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-\r
-## Import Modules\r
-#\r
-import sys\r
-import os\r
-import re\r
-import os.path as path\r
-import imp\r
-import copy\r
-from optparse import OptionParser\r
-from optparse import make_option\r
-\r
-import Common.EdkLogger\r
-import GenC\r
-import GenMake\r
-import GenDepex\r
-\r
-from StrGather import *\r
-from BuildEngine import *\r
-\r
-from Common.BuildToolError import *\r
-from Common.EdkIIWorkspaceBuild import *\r
-from Common.EdkIIWorkspace import *\r
-from Common.DataType import *\r
-from Common.Misc import *\r
-from Common.String import *\r
-from GenFds.FdfParser import *\r
-\r
-## Regular expression for splitting Dependency Expression stirng into tokens\r
-gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r
-\r
-## Mapping Makefile type\r
-gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}\r
-\r
-## Default output flag for all tools\r
-gDefaultOutputFlag = "-o "\r
-\r
-## Output flags for specific tools\r
-gOutputFlag = {\r
-    ("MSFT", "CC", "OUTPUT")      :   "/Fo",\r
-    ("MSFT", "SLINK", "OUTPUT")   :   "/OUT:",\r
-    ("MSFT", "DLINK", "OUTPUT")   :   "/OUT:",\r
-    ("MSFT", "ASMLINK", "OUTPUT") :   "/OUT:",\r
-    ("MSFT", "PCH", "OUTPUT")     :   "/Fp",\r
-    ("MSFT", "ASM", "OUTPUT")     :   "/Fo",\r
-\r
-    ("INTEL", "CC", "OUTPUT")          :   "/Fo",\r
-    ("INTEL", "SLINK", "OUTPUT")       :   "/OUT:",\r
-    ("INTEL", "DLINK", "OUTPUT")       :   "/OUT:",\r
-    ("INTEL", "ASMLINK", "OUTPUT")     :   "/OUT:",\r
-    ("INTEL", "PCH", "OUTPUT")         :   "/Fp",\r
-    ("INTEL", "ASM", "OUTPUT")         :   "/Fo",\r
-\r
-    ("GCC", "CC", "OUTPUT")        :   "-o ",\r
-    ("GCC", "SLINK", "OUTPUT")     :   "-cr ",\r
-    ("GCC", "DLINK", "OUTPUT")     :   "-o ",\r
-    ("GCC", "ASMLINK", "OUTPUT")   :   "-o ",\r
-    ("GCC", "PCH", "OUTPUT")       :   "-o ",\r
-    ("GCC", "ASM", "OUTPUT")       :   "-o ",\r
-}\r
-\r
-## Flag for include file search path\r
-gIncludeFlag = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I"}\r
-\r
-## Build rule configuration file\r
-gBuildRuleFile = 'Conf/build_rule.txt'\r
-\r
-## default file name for AutoGen\r
-gAutoGenCodeFileName = "AutoGen.c"\r
-gAutoGenHeaderFileName = "AutoGen.h"\r
-gAutoGenDepexFileName = "%(module_name)s.depex"\r
-\r
-## Base class for AutoGen\r
-#\r
-#   This class just implements the cache mechanism of AutoGen objects.\r
-#\r
-class AutoGen(object):\r
-    # database to maintain the objects of xxxAutoGen\r
-    _CACHE_ = {}    # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}\r
-\r
-    ## Factory method\r
-    #\r
-    #   @param  Class           class object of real AutoGen class\r
-    #                           (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)\r
-    #   @param  Workspace       Workspace directory or WorkspaceAutoGen object\r
-    #   @param  MetaFile        The path of meta file\r
-    #   @param  Target          Build target\r
-    #   @param  Toolchain       Tool chain name\r
-    #   @param  Arch            Target arch\r
-    #   @param  *args           The specific class related parameters\r
-    #   @param  **kwargs        The specific class related dict parameters\r
-    #\r
-    def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
-        # check if the object has been created\r
-        Key = (Target, Toolchain)\r
-        if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \\r
-           or MetaFile not in Class._CACHE_[Key][Arch]:\r
-            AutoGenObject = super(AutoGen, Class).__new__(Class)\r
-            # call real constructor\r
-            if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
-                return None\r
-            if Key not in Class._CACHE_:\r
-                Class._CACHE_[Key] = {}\r
-            if Arch not in Class._CACHE_[Key]:\r
-                Class._CACHE_[Key][Arch] = {}\r
-            Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject\r
-        else:\r
-            AutoGenObject = Class._CACHE_[Key][Arch][MetaFile]\r
-\r
-        return AutoGenObject\r
-\r
-    ## hash() operator\r
-    #\r
-    #  The file path of platform file will be used to represent hash value of this object\r
-    #\r
-    #   @retval int     Hash value of the file path of platform file\r
-    #\r
-    def __hash__(self):\r
-        return hash(self._MetaFile)\r
-\r
-    ## str() operator\r
-    #\r
-    #  The file path of platform file will be used to represent this object\r
-    #\r
-    #   @retval string  String of platform file path\r
-    #\r
-    def __str__(self):\r
-        return self._MetaFile\r
-\r
-    ## "==" operator\r
-    def __eq__(self, Other):\r
-        return Other != None and self._MetaFile == str(Other)\r
-\r
-## Workspace AutoGen class\r
-#\r
-#   This class is used mainly to control the whole platform build for different\r
-# architecture. This class will generate top level makefile.\r
-#\r
-class WorkspaceAutoGen(AutoGen):\r
-    ## Real constructor of WorkspaceAutoGen\r
-    #\r
-    # This method behaves the same as __init__ except that it needs explict invoke\r
-    # (in super class's __new__ method)\r
-    #\r
-    #   @param  WorkspaceDir            Root directory of workspace\r
-    #   @param  ActivePlatform          Meta-file of active platform\r
-    #   @param  Target                  Build target\r
-    #   @param  Toolchain               Tool chain name\r
-    #   @param  ArchList                List of architecture of current build\r
-    #   @param  MetaFileDb              Database containing meta-files\r
-    #   @param  BuildConfig             Configuration of build\r
-    #   @param  ToolDefinition          Tool chain definitions\r
-    #   @param  FlashDefinitionFile     File of flash definition\r
-    #   @param  Fds                     FD list to be generated\r
-    #   @param  Fvs                     FV list to be generated\r
-    #   @param  SkuId                   SKU id from command line\r
-    #\r
-    def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,\r
-              BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=[], Fvs=[], SkuId=''):\r
-        self._MetaFile      = str(ActivePlatform)\r
-        self.WorkspaceDir   = WorkspaceDir\r
-        self.Platform       = ActivePlatform\r
-        self.BuildTarget    = Target\r
-        self.ToolChain      = Toolchain\r
-        self.ArchList       = ArchList\r
-        self.SkuId          = SkuId\r
-\r
-        self.BuildDatabase  = MetaFileDb\r
-        self.TargetTxt      = BuildConfig\r
-        self.ToolDef        = ToolDefinition\r
-        self.FdfFile        = FlashDefinitionFile\r
-        self.FdTargetList   = Fds\r
-        self.FvTargetList   = Fvs\r
-        self.AutoGenObjectList = []\r
-\r
-        # there's many relative directory operations, so ...\r
-        os.chdir(self.WorkspaceDir)\r
-\r
-        # parse FDF file to get PCDs in it, if any\r
-        if self.FdfFile != None and self.FdfFile != '':\r
-            Fdf = FdfParser(os.path.join(self.WorkspaceDir, self.FdfFile))\r
-            Fdf.ParseFile()\r
-            PcdSet = Fdf.Profile.PcdDict\r
-            ModuleList = Fdf.Profile.InfList\r
-        else:\r
-            PcdSet = {}\r
-            ModuleList = []\r
-\r
-        # apply SKU and inject PCDs from Flash Definition file\r
-        for Arch in self.ArchList:\r
-            Platform = self.BuildDatabase[self._MetaFile, Arch]\r
-            Platform.SkuName = self.SkuId\r
-            for Name, Guid in PcdSet:\r
-                Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])\r
-\r
-            Pa = PlatformAutoGen(self, self._MetaFile, Target, Toolchain, Arch)\r
-            self.AutoGenObjectList.append(Pa)\r
-\r
-        self._BuildDir = None\r
-        self._FvDir = None\r
-        self._MakeFileDir = None\r
-        self._BuildCommand = None\r
-\r
-        return True\r
-\r
-    ## Return the directory to store FV files\r
-    def _GetFvDir(self):\r
-        if self._FvDir == None:\r
-            self._FvDir = path.join(self.BuildDir, 'FV')\r
-        return self._FvDir\r
-\r
-    ## Return the directory to store all intermediate and final files built\r
-    def _GetBuildDir(self):\r
-        return self.AutoGenObjectList[0].BuildDir\r
-\r
-    ## Return the build output directory platform specifies\r
-    def _GetOutputDir(self):\r
-        return self.Platform.OutputDirectory\r
-\r
-    ## Return platform name\r
-    def _GetName(self):\r
-        return self.Platform.PlatformName\r
-\r
-    ## Return meta-file GUID\r
-    def _GetGuid(self):\r
-        return self.Platform.Guid\r
-\r
-    ## Return platform version\r
-    def _GetVersion(self):\r
-        return self.Platform.Version\r
-\r
-    ## Return paths of tools\r
-    def _GetToolPaths(self):\r
-        return self.AutoGenObjectList[0].ToolPath\r
-\r
-    ## Return options of tools\r
-    def _GetToolOptions(self):\r
-        return self.AutoGenObjectList[0].ToolOption\r
-\r
-    ## Return directory of platform makefile\r
-    #\r
-    #   @retval     string  Makefile directory\r
-    #\r
-    def _GetMakeFileDir(self):\r
-        if self._MakeFileDir == None:\r
-            self._MakeFileDir = self.BuildDir\r
-        return self._MakeFileDir\r
-\r
-    ## Return build command string\r
-    #\r
-    #   @retval     string  Build command string\r
-    #\r
-    def _GetBuildCommand(self):\r
-        if self._BuildCommand == None:\r
-            # BuildCommand should be all the same. So just get one from platform AutoGen\r
-            self._BuildCommand = self.AutoGenObjectList[0].BuildCommand\r
-        return self._BuildCommand\r
-\r
-    ## Create makefile for the platform and mdoules in it\r
-    #\r
-    #   @param      CreateDepsMakeFile      Flag indicating if the makefile for\r
-    #                                       modules will be created as well\r
-    #\r
-    def CreateMakeFile(self, CreateDepsMakeFile=False):\r
-        # create makefile for platform\r
-        Makefile = GenMake.TopLevelMakefile(self)\r
-        if Makefile.Generate():\r
-            EdkLogger.verbose("Generated makefile for platform [%s] %s\n" %\r
-                           (self._MetaFile, self.ArchList))\r
-        else:\r
-            EdkLogger.verbose("Skipped the generation of makefile for platform [%s] %s\n" %\r
-                           (self._MetaFile, self.ArchList))\r
-\r
-        if CreateDepsMakeFile:\r
-            for Pa in self.AutoGenObjectList:\r
-                Pa.CreateMakeFile(CreateDepsMakeFile)\r
-\r
-    ## Create autogen code for platform and modules\r
-    #\r
-    #  Since there's no autogen code for platform, this method will do nothing\r
-    #  if CreateModuleCodeFile is set to False.\r
-    #\r
-    #   @param      CreateDepsCodeFile      Flag indicating if creating module's\r
-    #                                       autogen code file or not\r
-    #\r
-    def CreateCodeFile(self, CreateDepsCodeFile=False):\r
-        if not CreateDepsCodeFile:\r
-            return\r
-        for Pa in self.AutoGenObjectList:\r
-            Pa.CreateCodeFile(CreateDepsCodeFile)\r
-\r
-    Name                = property(_GetName)\r
-    Guid                = property(_GetGuid)\r
-    Version             = property(_GetVersion)\r
-    OutputDir           = property(_GetOutputDir)\r
-\r
-    ToolPath            = property(_GetToolPaths)       # toolcode : tool path\r
-    ToolOption          = property(_GetToolOptions)     # toolcode : tool option string\r
-\r
-    BuildDir            = property(_GetBuildDir)\r
-    FvDir               = property(_GetFvDir)\r
-    MakeFileDir         = property(_GetMakeFileDir)\r
-    BuildCommand        = property(_GetBuildCommand)\r
-\r
-## AutoGen class for platform\r
-#\r
-#  PlatformAutoGen class will process the original information in platform\r
-#  file in order to generate makefile for platform.\r
-#\r
-class PlatformAutoGen(AutoGen):\r
-    ## The real constructor of PlatformAutoGen\r
-    #\r
-    #  This method is not supposed to be called by users of PlatformAutoGen. It's\r
-    #  only used by factory method __new__() to do real initialization work for an\r
-    #  object of PlatformAutoGen\r
-    #\r
-    #   @param      Workspace       EdkIIWorkspaceBuild object\r
-    #   @param      PlatformFile    Platform file (DSC file)\r
-    #   @param      Target          Build target (DEBUG, RELEASE)\r
-    #   @param      Toolchain       Name of tool chain\r
-    #   @param      Arch            arch of the platform supports\r
-    #\r
-    def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):\r
-        EdkLogger.verbose("\nAutoGen platform [%s] [%s]" % (PlatformFile, Arch))\r
-\r
-        self._MetaFile = str(PlatformFile)\r
-        self.Workspace = Workspace\r
-        self.WorkspaceDir = Workspace.WorkspaceDir\r
-        self.ToolChain = Toolchain\r
-        self.BuildTarget = Target\r
-        self.Arch = Arch\r
-        self.SourceDir = path.dirname(PlatformFile)\r
-        self.FdTargetList = self.Workspace.FdTargetList\r
-        self.FvTargetList = self.Workspace.FvTargetList\r
-\r
-        # flag indicating if the makefile/C-code file has been created or not\r
-        self.IsMakeFileCreated  = False\r
-        self.IsCodeFileCreated  = False\r
-\r
-        self._Platform   = None\r
-        self._Name       = None\r
-        self._Guid       = None\r
-        self._Version    = None\r
-\r
-        self._BuildRule = None\r
-        self._SourceDir = None\r
-        self._BuildDir = None\r
-        self._OutputDir = None\r
-        self._FvDir = None\r
-        self._MakeFileDir = None\r
-        self._FdfFile = None\r
-\r
-        self._PcdTokenNumber = None    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber\r
-        self._DynamicPcdList = None    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
-        self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
-\r
-        self._ToolPath = None          # toolcode : tool path\r
-        self._ToolDllPath = None       # toolcode : lib path\r
-        self._ToolStaticLib = None     # toolcode : lib path\r
-        self._ToolChainFamily = None   # toolcode : tool chain family\r
-        self._BuildOption = None       # toolcode : option\r
-        self._OutputFlag = None        # toolcode : output flag\r
-        self._IncludeFlag = None       # toolcode : include flag\r
-        self._ToolOption = None        # toolcode : tool option string\r
-        self._PackageList = None\r
-        self._ModuleAutoGenList  = None\r
-        self._LibraryAutoGenList = None\r
-        self._BuildCommand = None\r
-\r
-        # get the original module/package/platform objects\r
-        self.BuildDatabase = Workspace.BuildDatabase\r
-        return True\r
-\r
-    ## Create autogen code for platform and modules\r
-    #\r
-    #  Since there's no autogen code for platform, this method will do nothing\r
-    #  if CreateModuleCodeFile is set to False.\r
-    #\r
-    #   @param      CreateModuleCodeFile    Flag indicating if creating module's\r
-    #                                       autogen code file or not\r
-    #\r
-    def CreateCodeFile(self, CreateModuleCodeFile=False):\r
-        # only module has code to be greated, so do nothing if CreateModuleCodeFile is False\r
-        if self.IsCodeFileCreated or not CreateModuleCodeFile:\r
-            return\r
-\r
-        for Ma in self.ModuleAutoGenList:\r
-            Ma.CreateCodeFile(True)\r
-\r
-        # don't do this twice\r
-        self.IsCodeFileCreated = True\r
-\r
-    ## Create makefile for the platform and mdoules in it\r
-    #\r
-    #   @param      CreateModuleMakeFile    Flag indicating if the makefile for\r
-    #                                       modules will be created as well\r
-    #\r
-    def CreateMakeFile(self, CreateModuleMakeFile=False):\r
-        if CreateModuleMakeFile:\r
-            for ModuleFile in self.Platform.Modules:\r
-                Ma = ModuleAutoGen(self.Workspace, ModuleFile,\r
-                                              self.BuildTarget, self.ToolChain,\r
-                                              self.Arch, self._MetaFile)\r
-                Ma.CreateMakeFile(True)\r
-\r
-        # no need to create makefile for the platform more than once\r
-        if self.IsMakeFileCreated:\r
-            return\r
-\r
-        # create makefile for platform\r
-        Makefile = GenMake.PlatformMakefile(self)\r
-        if Makefile.Generate():\r
-            EdkLogger.verbose("Generated makefile for platform [%s] [%s]\n" %\r
-                           (self._MetaFile, self.Arch))\r
-        else:\r
-            EdkLogger.verbose("Skipped the generation of makefile for platform [%s] [%s]\n" %\r
-                           (self._MetaFile, self.Arch))\r
-        self.IsMakeFileCreated = True\r
-\r
-    ## Return the platform build data object\r
-    def _GetPlatform(self):\r
-        if self._Platform == None:\r
-            self._Platform = self.BuildDatabase[self._MetaFile, self.Arch]\r
-        return self._Platform\r
-\r
-    ## Return platform name\r
-    def _GetName(self):\r
-        return self.Platform.PlatformName\r
-\r
-    ## Return the meta file GUID\r
-    def _GetGuid(self):\r
-        return self.Platform.Guid\r
-\r
-    ## Return the platform version\r
-    def _GetVersion(self):\r
-        return self.Platform.Version\r
-\r
-    ## Return the FDF file name\r
-    def _GetFdfFile(self):\r
-        if self._FdfFile == None:\r
-            if self.Workspace.FdfFile != "":\r
-                self._FdfFile= path.join(self.WorkspaceDir, self.Workspace.FdfFile)\r
-            else:\r
-                self._FdfFile = ''\r
-        return self._FdfFile\r
-\r
-    ## Return the build output directory platform specifies\r
-    def _GetOutputDir(self):\r
-        return self.Platform.OutputDirectory\r
-\r
-    ## Return the directory to store all intermediate and final files built\r
-    def _GetBuildDir(self):\r
-        if self._BuildDir == None:\r
-            if os.path.isabs(self.OutputDir):\r
-                self._BuildDir = path.join(\r
-                                            path.abspath(self.OutputDir),\r
-                                            self.BuildTarget + "_" + self.ToolChain,\r
-                                            )\r
-            else:\r
-                self._BuildDir = path.join(\r
-                                            self.WorkspaceDir,\r
-                                            self.OutputDir,\r
-                                            self.BuildTarget + "_" + self.ToolChain,\r
-                                            )\r
-        return self._BuildDir\r
-\r
-    ## Return directory of platform makefile\r
-    #\r
-    #   @retval     string  Makefile directory\r
-    #\r
-    def _GetMakeFileDir(self):\r
-        if self._MakeFileDir == None:\r
-            self._MakeFileDir = path.join(self.BuildDir, self.Arch)\r
-        return self._MakeFileDir\r
-\r
-    ## Return build command string\r
-    #\r
-    #   @retval     string  Build command string\r
-    #\r
-    def _GetBuildCommand(self):\r
-        if self._BuildCommand == None:\r
-            self._BuildCommand = tuple()\r
-            if "MAKE" in self.ToolPath:\r
-                self._BuildCommand += (self.ToolPath["MAKE"],)\r
-                if "MAKE" in self.ToolOption:\r
-                    NewOption = self.ToolOption["MAKE"].strip()\r
-                    if NewOption != '':\r
-                      self._BuildCommand += (NewOption,)\r
-        return self._BuildCommand\r
-\r
-    ## Get tool chain definition\r
-    #\r
-    #  Get each tool defition for given tool chain from tools_def.txt and platform\r
-    #\r
-    def _GetToolDefinition(self):\r
-        ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary\r
-        ToolCodeList = self.Workspace.ToolDef.ToolsDefTxtDatabase["COMMAND_TYPE"]\r
-        self._ToolPath = {}\r
-        self._ToolDllPath = {}\r
-        self._ToolChainFamily = {}\r
-        self._ToolOption = {}\r
-        self._OutputFlag = {}\r
-        self._IncludeFlag = {}\r
-        for Tool in ToolCodeList:\r
-            KeyBaseString = "%s_%s_%s_%s" % (self.BuildTarget, self.ToolChain, self.Arch, Tool)\r
-\r
-            Key = "%s_PATH" % KeyBaseString\r
-            if Key not in ToolDefinition:\r
-                continue\r
-            Path = ToolDefinition[Key]\r
-\r
-            Key = "%s_FAMILY" % KeyBaseString\r
-            if Key in ToolDefinition:\r
-                Family = ToolDefinition[Key]\r
-            else:\r
-                Family = ""\r
-\r
-            Key = "%s_FLAGS" % KeyBaseString\r
-            if Key in ToolDefinition:\r
-                Option = ToolDefinition[Key]\r
-            else:\r
-                Option = ""\r
-\r
-            Key = "%s_DLL" % KeyBaseString\r
-            if Key in ToolDefinition:\r
-                Dll = ToolDefinition[Key]\r
-                # set the DLL path in system's PATH environment\r
-                os.environ["PATH"] = Dll + os.pathsep + os.environ["PATH"]\r
-            else:\r
-                Dll = ""\r
-\r
-            Key = KeyBaseString + "_OUTPUT"\r
-            if Key in ToolDefinition:\r
-                OutputFlag = ToolDefinition[Key]\r
-            elif (Family, Tool, "OUTPUT") in gOutputFlag:\r
-                OutputFlag = gOutputFlag[Family, Tool, "OUTPUT"]\r
-                if OutputFlag[0] == '"' and OutputFlag[-1] == '"':\r
-                    OutputFlag = OutputFlag[1:-1]\r
-            else:\r
-                OutputFlag = gDefaultOutputFlag\r
-\r
-            InputFlag = gIncludeFlag[Family]\r
-\r
-            self._ToolPath[Tool] = Path\r
-            self._ToolDllPath[Tool] = Dll\r
-            self._ToolChainFamily[Tool] = Family\r
-            self._ToolOption[Tool] = Option\r
-            self._OutputFlag[Tool] = OutputFlag\r
-            self._IncludeFlag[Tool] = InputFlag\r
-\r
-    ## Return the paths of tools\r
-    def _GetToolPaths(self):\r
-        if self._ToolPath == None:\r
-            self._GetToolDefinition()\r
-        return self._ToolPath\r
-\r
-    ## Return the dll paths of tools\r
-    def _GetToolDllPaths(self):\r
-        if self._ToolDllPath == None:\r
-            self._GetToolDefinition()\r
-        return self._ToolDllPath\r
-\r
-    ## Return the static libraries of tools\r
-    def _GetToolStaticLibs(self):\r
-        if self._ToolStaticLib == None:\r
-            self._GetToolDefinition()\r
-        return self._ToolStaticLib\r
-\r
-    ## Return the families of tools\r
-    def _GetToolChainFamilies(self):\r
-        if self._ToolChainFamily == None:\r
-            self._GetToolDefinition()\r
-        return self._ToolChainFamily\r
-\r
-    ## Return the build options specific to this platform\r
-    def _GetBuildOptions(self):\r
-        if self._BuildOption == None:\r
-            self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)\r
-        return self._BuildOption\r
-\r
-    ## Return the output flag of tools\r
-    def _GetOuputFlags(self):\r
-        if self._OutputFlag == None:\r
-            self._GetToolDefinition()\r
-        return self._OutputFlag\r
-\r
-    ## Return the include flags of tools\r
-    def _GetIncludeFlags(self):\r
-        if self._IncludeFlag == None:\r
-            self._GetToolDefinition()\r
-        return self._IncludeFlag\r
-\r
-    ## Return the default options of tools\r
-    def _GetToolOptions(self):\r
-        if self._ToolOption == None:\r
-            self._GetToolDefinition()\r
-        return self._ToolOption\r
-\r
-    ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt\r
-    #\r
-    #   @retval     BuildRule object\r
-    #\r
-    def _GetBuildRule(self):\r
-        if self._BuildRule == None:\r
-            BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
-            if BuildRuleFile in [None, '']:\r
-                BuildRuleFile = gBuildRuleFile\r
-            self._BuildRule = BuildRule(BuildRuleFile)\r
-        return self._BuildRule\r
-\r
-    ## Summarize the packages used by modules in this platform\r
-    def _GetPackageList(self):\r
-        if self._PackageList == None:\r
-            self._PackageList = set()\r
-            for La in self.LibraryAutoGenList:\r
-                self._PackageList.update(La.DependentPackageList)\r
-            for Ma in self.ModuleAutoGenList:\r
-                self._PackageList.update(Ma.DependentPackageList)\r
-        return self._PackageList\r
-\r
-    ## Collect dynamic PCDs\r
-    #\r
-    #  Gather dynamic PCDs list from each module and their settings from platform\r
-    #\r
-    def _GetPcdList(self):\r
-        self._NonDynamicPcdList = []\r
-        self._DynamicPcdList = []\r
-\r
-        # for gathering error information\r
-        NotFoundPcdList = set()\r
-        NoDatumTypePcdList = set()\r
-\r
-        self._GuidValue = {}\r
-        for F in self.Platform.Modules:\r
-            M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self._MetaFile)\r
-            #GuidValue.update(M.Guids)\r
-            for PcdFromModule in M.PcdList:\r
-                # check if the setting of the PCD is found in platform\r
-                #if not PcdFromModule.IsOverrided:\r
-                #    NotFoundPcdList.add("%s [%s]" % (" | ".join(Key), F))\r
-                #    continue\r
-\r
-                # make sure that the "VOID*" kind of datum has MaxDatumSize set\r
-                if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize == None:\r
-                    NoDatumTypePcdList.add("%s [%s]" % (" | ".join(Key), F))\r
-\r
-                if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:\r
-                    # for autogen code purpose\r
-                    if M.ModuleType in ["PEIM", "PEI_CORE"]:\r
-                        PcdFromModule.Phase = "PEI"\r
-                    if PcdFromModule not in self._DynamicPcdList:\r
-                        self._DynamicPcdList.append(PcdFromModule)\r
-                elif PcdFromModule not in self._NonDynamicPcdList:\r
-                    self._NonDynamicPcdList.append(PcdFromModule)\r
-\r
-        # print out error information and break the build, if error found\r
-        if len(NoDatumTypePcdList) > 0:\r
-            NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "PCD setting error",\r
-                            ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"\r
-                                      % NoDatumTypePcdListString)\r
-\r
-    ## Get list of non-dynamic PCDs\r
-    def _GetNonDynamicPcdList(self):\r
-        if self._NonDynamicPcdList == None:\r
-            self._GetPcdList()\r
-        return self._NonDynamicPcdList\r
-\r
-    ## Get list of dynamic PCDs\r
-    def _GetDynamicPcdList(self):\r
-        if self._DynamicPcdList == None:\r
-            self._GetPcdList()\r
-        return self._DynamicPcdList\r
-\r
-    ## Generate Token Number for all PCD\r
-    def _GetPcdTokenNumbers(self):\r
-        if self._PcdTokenNumber == None:\r
-            self._PcdTokenNumber = sdict()\r
-            TokenNumber = 1\r
-            for Pcd in self.DynamicPcdList:\r
-                if Pcd.Phase == "PEI":\r
-                    EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
-                    self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
-                    TokenNumber += 1\r
-\r
-            for Pcd in self.DynamicPcdList:\r
-                if Pcd.Phase == "DXE":\r
-                    EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
-                    self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
-                    TokenNumber += 1\r
-\r
-            for Pcd in self.NonDynamicPcdList:\r
-                self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
-                TokenNumber += 1\r
-        return self._PcdTokenNumber\r
-\r
-    ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform\r
-    def _GetAutoGenObjectList(self):\r
-        self._ModuleAutoGenList = []\r
-        self._LibraryAutoGenList = []\r
-        for ModuleFile in self.Platform.Modules:\r
-            Ma = ModuleAutoGen(\r
-                    self.Workspace,\r
-                    ModuleFile,\r
-                    self.BuildTarget,\r
-                    self.ToolChain,\r
-                    self.Arch,\r
-                    self._MetaFile\r
-                    )\r
-            if Ma not in self._ModuleAutoGenList:\r
-                self._ModuleAutoGenList.append(Ma)\r
-            for La in Ma.LibraryAutoGenList:\r
-                if La not in self._LibraryAutoGenList:\r
-                    self._LibraryAutoGenList.append(La)\r
-\r
-    ## Summarize ModuleAutoGen objects of all modules to be built for this platform\r
-    def _GetModuleAutoGenList(self):\r
-        if self._ModuleAutoGenList == None:\r
-            self._GetAutoGenObjectList()\r
-        return self._ModuleAutoGenList\r
-\r
-    ## Summarize ModuleAutoGen objects of all libraries to be built for this platform\r
-    def _GetLibraryAutoGenList(self):\r
-        if self._LibraryAutoGenList == None:\r
-            self._GetAutoGenObjectList()\r
-        return self._LibraryAutoGenList\r
-\r
-    ## Test if a module is supported by the platform\r
-    #\r
-    #  An error will be raised directly if the module or its arch is not supported\r
-    #  by the platform or current configuration\r
-    #\r
-    def ValidModule(self, Module):\r
-        return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances\r
-\r
-    ## Resolve the library classes in a module to library instances\r
-    #\r
-    # This method will not only resolve library classes but also sort the library\r
-    # instances according to the dependency-ship.\r
-    #\r
-    #   @param  Module      The module from which the library classes will be resolved\r
-    #\r
-    #   @retval library_list    List of library instances sorted\r
-    #\r
-    def ApplyLibraryInstance(self, Module):\r
-        ModuleType = Module.ModuleType\r
-        # apply library instances from platform\r
-        for LibraryClass in Module.LibraryClasses:\r
-            LibraryInstance = self.Platform.LibraryClasses[LibraryClass, ModuleType]\r
-            if LibraryInstance == None:\r
-                continue\r
-            Module.LibraryClasses[LibraryClass] = LibraryInstance\r
-\r
-        # override library instances with module specific setting\r
-        PlatformModule = self.Platform.Modules[str(Module)]\r
-        for LibraryClass in PlatformModule.LibraryClasses:\r
-            Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]\r
-\r
-        # R9 module\r
-        LibraryConsumerList = [Module]\r
-        Constructor         = []\r
-        ConsumedByList      = sdict()\r
-        LibraryInstance     = sdict()\r
-\r
-        EdkLogger.verbose("")\r
-        EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
-        while len(LibraryConsumerList) > 0:\r
-            M = LibraryConsumerList.pop()\r
-            for LibraryClassName in M.LibraryClasses:\r
-                LibraryPath = M.LibraryClasses[LibraryClassName]\r
-                if LibraryPath == None or LibraryPath == "":\r
-                    LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]\r
-                    if LibraryPath == None and LibraryClassName not in LibraryInstance:\r
-                        LibraryInstance[LibraryClassName] = None\r
-                        continue\r
-                if LibraryClassName not in LibraryInstance:\r
-                    LibraryModule = self.BuildDatabase[LibraryPath, self.Arch]\r
-                    # for those forced library instance (NULL library), add a fake library class\r
-                    if LibraryClassName.startswith("NULL"):\r
-                        LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))\r
-                    elif ModuleType not in LibraryModule.LibraryClass[0].SupModList:\r
-                        EdkLogger.error("build", OPTION_MISSING,\r
-                                        "Module type [%s] is not supported by library instance [%s]" \\r
-                                        % (ModuleType, LibraryPath), File=self._MetaFile,\r
-                                        ExtraData="\tconsumed by [%s]" % str(Module))\r
-\r
-                    LibraryInstance[LibraryClassName] = LibraryModule\r
-                    LibraryConsumerList.append(LibraryModule)\r
-                    EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))\r
-                else:\r
-                    LibraryModule = LibraryInstance[LibraryClassName]\r
-\r
-                if LibraryModule == None:\r
-                    continue\r
-\r
-                if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:\r
-                    Constructor.append(LibraryModule)\r
-\r
-                if LibraryModule not in ConsumedByList:\r
-                    ConsumedByList[LibraryModule] = []\r
-                # don't add current module itself to consumer list\r
-                if M != Module:\r
-                    if M in ConsumedByList[LibraryModule]:\r
-                        continue\r
-                    ConsumedByList[LibraryModule].append(M)\r
-        #\r
-        # Initialize the sorted output list to the empty set\r
-        #\r
-        SortedLibraryList = []\r
-        #\r
-        # Q <- Set of all nodes with no incoming edges\r
-        #\r
-        LibraryList = [] #LibraryInstance.values()\r
-        Q = []\r
-        for LibraryClassName in LibraryInstance:\r
-            M = LibraryInstance[LibraryClassName]\r
-            if M == None:\r
-                EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,\r
-                                "Library instance of library class [%s] is not found" % LibraryClassName,\r
-                                File=self._MetaFile, ExtraData="consumed by [%s] [%s]" % (str(Module), self.Arch))\r
-            LibraryList.append(M)\r
-            #\r
-            # check if there're library classes\r
-            #\r
-            #for Lc in M.LibraryClass:\r
-            #    if Lc.SupModList != None and ModuleType not in Lc.SupModList:\r
-            #        EdkLogger.error("build", OPTION_MISSING,\r
-            #                        "Module type [%s] is not supported by library instance [%s]" % (ModuleType, str(M)),\r
-            #                        File=self._MetaFile, ExtraData="\tconsumed by [%s]" % str(Module))\r
-\r
-                #if Lc.LibraryClass in LibraryInstance and str(M) != str(LibraryInstance[Lc.LibraryClass]):\r
-                #    EdkLogger.error("build", OPTION_CONFLICT,\r
-                #                    "More than one library instance found for library class [%s] in module [%s]" % (Lc.LibraryClass, str(Module)),\r
-                #                    ExtraData="\t%s\n\t%s" % (LibraryInstance[Lc.LibraryClass], str(M))\r
-                #                    )\r
-            if ConsumedByList[M] == []:\r
-                Q.insert(0, M)\r
-\r
-        #\r
-        # start the  DAG algorithm\r
-        #\r
-        while True:\r
-            EdgeRemoved = True\r
-            while Q == [] and EdgeRemoved:\r
-                EdgeRemoved = False\r
-                # for each node Item with a Constructor\r
-                for Item in LibraryList:\r
-                    if Item not in Constructor:\r
-                        continue\r
-                    # for each Node without a constructor with an edge e from Item to Node\r
-                    for Node in ConsumedByList[Item]:\r
-                        if Node in Constructor:\r
-                            continue\r
-                        # remove edge e from the graph if Node has no constructor\r
-                        ConsumedByList[Item].remove(Node)\r
-                        EdgeRemoved = True\r
-                        if ConsumedByList[Item] == []:\r
-                            # insert Item into Q\r
-                            Q.insert(0, Item)\r
-                            break\r
-                    if Q != []:\r
-                        break\r
-            # DAG is done if there's no more incoming edge for all nodes\r
-            if Q == []:\r
-                break\r
-\r
-            # remove node from Q\r
-            Node = Q.pop()\r
-            # output Node\r
-            SortedLibraryList.append(Node)\r
-\r
-            # for each node Item with an edge e from Node to Item do\r
-            for Item in LibraryList:\r
-                if Node not in ConsumedByList[Item]:\r
-                    continue\r
-                # remove edge e from the graph\r
-                ConsumedByList[Item].remove(Node)\r
-\r
-                if ConsumedByList[Item] != []:\r
-                    continue\r
-                # insert Item into Q, if Item has no other incoming edges\r
-                Q.insert(0, Item)\r
-\r
-        #\r
-        # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle\r
-        #\r
-        for Item in LibraryList:\r
-            if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:\r
-                ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])\r
-                EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),\r
-                                ExtraData=ErrorMessage, File=self._MetaFile)\r
-            if Item not in SortedLibraryList:\r
-                SortedLibraryList.append(Item)\r
-\r
-        #\r
-        # Build the list of constructor and destructir names\r
-        # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order\r
-        #\r
-        SortedLibraryList.reverse()\r
-        return SortedLibraryList\r
-\r
-\r
-    ## Override PCD setting (type, value, ...)\r
-    #\r
-    #   @param  ToPcd       The PCD to be overrided\r
-    #   @param  FromPcd     The PCD overrideing from\r
-    #\r
-    def _OverridePcd(self, ToPcd, FromPcd, Module=""):\r
-        #\r
-        # in case there's PCDs coming from FDF file, which have no type given.\r
-        # at this point, ToPcd.Type has the type found from dependent\r
-        # package\r
-        #\r
-        if FromPcd != None:\r
-            if ToPcd.Pending and FromPcd.Type not in [None, '']:\r
-                ToPcd.Type = FromPcd.Type\r
-            elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \\r
-                and ToPcd.Type != FromPcd.Type:\r
-                EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",\r
-                                ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\\r
-                                          % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName,\r
-                                             ToPcd.Type, Module, FromPcd.Type),\r
-                                          File=self._MetaFile)\r
-\r
-            if FromPcd.MaxDatumSize not in [None, '']:\r
-                ToPcd.MaxDatumSize = FromPcd.MaxDatumSize\r
-            if FromPcd.DefaultValue not in [None, '']:\r
-                ToPcd.DefaultValue = FromPcd.DefaultValue\r
-            if FromPcd.TokenValue not in [None, '']:\r
-                ToPcd.TokenValue = FromPcd.TokenValue\r
-            if FromPcd.MaxDatumSize not in [None, '']:\r
-                ToPcd.MaxDatumSize = FromPcd.MaxDatumSize\r
-            if FromPcd.DatumType not in [None, '']:\r
-                ToPcd.DatumType = FromPcd.DatumType\r
-            if FromPcd.SkuInfoList not in [None, '', []]:\r
-                ToPcd.SkuInfoList = FromPcd.SkuInfoList\r
-\r
-        if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:\r
-            EdkLogger.verbose("No MaxDatumSize specified for PCD %s.%s" \\r
-                              % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))\r
-            Value = ToPcd.DefaultValue\r
-            if Value[0] == 'L':\r
-                ToPcd.MaxDatumSize = str(len(Value) * 2)\r
-            elif Value[0] == '{':\r
-                ToPcd.MaxDatumSize = str(len(Value.split(',')))\r
-            else:\r
-                ToPcd.MaxDatumSize = str(len(Value))\r
-\r
-        # apply default SKU for dynamic PCDS if specified one is not available\r
-        if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \\r
-            and ToPcd.SkuInfoList in [None, {}, '']:\r
-            if self.Platform.SkuName in self.Platform.SkuIds:\r
-                SkuName = self.Platform.SkuName\r
-            else:\r
-                SkuName = 'DEFAULT'\r
-            ToPcd.SkuInfoList = {\r
-                SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue)\r
-            }\r
-\r
-    ## Apply PCD setting defined platform to a module\r
-    #\r
-    #   @param  Module  The module from which the PCD setting will be overrided\r
-    #\r
-    #   @retval PCD_list    The list PCDs with settings from platform\r
-    #\r
-    def ApplyPcdSetting(self, Module):\r
-        # for each PCD in module\r
-        for Name,Guid in Module.Pcds:\r
-            PcdInModule = Module.Pcds[Name,Guid]\r
-            # find out the PCD setting in platform\r
-            if (Name,Guid) in self.Platform.Pcds:\r
-                PcdInPlatform = self.Platform.Pcds[Name,Guid]\r
-            else:\r
-                PcdInPlatform = None\r
-            # then override the settings if any\r
-            self._OverridePcd(PcdInModule, PcdInPlatform, Module)\r
-            # resolve the VariableGuid value\r
-            for SkuId in PcdInModule.SkuInfoList:\r
-                Sku = PcdInModule.SkuInfoList[SkuId]\r
-                if Sku.VariableGuid == '': continue\r
-                Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList)\r
-                if Sku.VariableGuidValue == None:\r
-                    PackageList = '\t' + "\n\t".join([str(P) for P in Module.Packages])\r
-                    EdkLogger.error(\r
-                                'build',\r
-                                RESOURCE_NOT_AVAILABLE,\r
-                                "Value of [%s] is not found in" % Sku.VariableGuid,\r
-                                ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \\r
-                                                        % (Guid, Name, str(Module)),\r
-                                File=self._MetaFile\r
-                                )\r
-\r
-        # override PCD settings with module specific setting\r
-        if Module in self.Platform.Modules:\r
-            PlatformModule = self.Platform.Modules[str(Module)]\r
-            for Key  in PlatformModule.Pcds:\r
-                if Key in Module.Pcds:\r
-                    self._OverridePcd(Module.Pcds[Key], PlatformModule.Pcds[Key], Module)\r
-        return Module.Pcds.values()\r
-\r
-    ## Resolve library names to library modules\r
-    #\r
-    # (for R8.x modules)\r
-    #\r
-    #   @param  Module  The module from which the library names will be resolved\r
-    #\r
-    #   @retval library_list    The list of library modules\r
-    #\r
-    def ResolveLibraryReference(self, Module):\r
-        EdkLogger.verbose("")\r
-        EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
-        LibraryConsumerList = [Module]\r
-\r
-        # "CompilerStub" is a must for R8 modules\r
-        Module.Libraries.append("CompilerStub")\r
-        LibraryList = []\r
-        while len(LibraryConsumerList) > 0:\r
-            M = LibraryConsumerList.pop()\r
-            for LibraryName in M.Libraries:\r
-                Library = self.Platform.LibraryClasses[LibraryName, ':dummy:']\r
-                if Library == None:\r
-                    EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),\r
-                                    ExtraData="\t%s [%s]" % (str(Module), self.Arch))\r
-                    continue\r
-\r
-                if Library not in LibraryList:\r
-                    LibraryList.append(Library)\r
-                    LibraryConsumerList.append(Library)\r
-                    EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library)))\r
-        return LibraryList\r
-\r
-    ## Expand * in build option key\r
-    #\r
-    #   @param  Options     Options to be expanded\r
-    #\r
-    #   @retval options     Options expanded\r
-    #\r
-    def _ExpandBuildOption(self, Options):\r
-        BuildOptions = {}\r
-        for Key in Options:\r
-            Family = Key[0]\r
-            Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
-            # if no tool defined for the option, skip it\r
-            if Tool not in self.Workspace.ToolPath:\r
-                continue\r
-            # if tool chain family doesn't match, skip it\r
-            if Family != None and Family != "" and Family != self.ToolChainFamily[Tool]:\r
-                continue\r
-            # expand any wildcard\r
-            if Target == "*" or Target == self.BuildTarget:\r
-                if Tag == "*" or Tag == self.ToolChain:\r
-                    if Arch == "*" or Arch == self.Arch:\r
-                        if Tool not in BuildOptions:\r
-                            BuildOptions[Tool] = Options[Key]\r
-                        else:\r
-                            # append options for the same tool\r
-                            BuildOptions[Tool] += " " + Options[Key]\r
-        return BuildOptions\r
-\r
-    ## Append build options in platform to a module\r
-    #\r
-    #   @param  Module  The module to which the build options will be appened\r
-    #\r
-    #   @retval options     The options appended with build options in platform\r
-    #\r
-    def ApplyBuildOption(self, Module):\r
-        PlatformOptions = self.BuildOption\r
-        ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)\r
-        if Module in self.Platform.Modules:\r
-            PlatformModule = self.Platform.Modules[str(Module)]\r
-            PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)\r
-        else:\r
-            PlatformModuleOptions = {}\r
-\r
-        BuildOptions = {}\r
-        # for those tools that have no option in module file, give it a empty string\r
-        for Tool in self.Workspace.ToolPath:\r
-            if Tool in self.ToolOption and Module.ModuleType != 'USER_DEFINED':\r
-                BuildOptions[Tool] = self.ToolOption[Tool]\r
-            else:\r
-                BuildOptions[Tool] = ''\r
-            if Tool in ModuleOptions:\r
-                BuildOptions[Tool] += " " + ModuleOptions[Tool]\r
-            if Tool in PlatformOptions:\r
-                BuildOptions[Tool] += " " + PlatformOptions[Tool]\r
-            if Tool in PlatformModuleOptions:\r
-                BuildOptions[Tool] += " " + PlatformModuleOptions[Tool]\r
-        return BuildOptions\r
-\r
-    Platform            = property(_GetPlatform)\r
-    Name                = property(_GetName)\r
-    Guid                = property(_GetGuid)\r
-    Version             = property(_GetVersion)\r
-\r
-    OutputDir           = property(_GetOutputDir)\r
-    BuildDir            = property(_GetBuildDir)\r
-    MakeFileDir         = property(_GetMakeFileDir)\r
-    FdfFile             = property(_GetFdfFile)\r
-\r
-    PcdTokenNumber      = property(_GetPcdTokenNumbers)    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber\r
-    DynamicPcdList      = property(_GetDynamicPcdList)    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
-    NonDynamicPcdList   = property(_GetNonDynamicPcdList)    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
-    PackageList         = property(_GetPackageList)\r
-\r
-    ToolPath            = property(_GetToolPaths)    # toolcode : tool path\r
-    ToolDllPath         = property(_GetToolDllPaths)    # toolcode : lib path\r
-    ToolStaticLib       = property(_GetToolStaticLibs)    # toolcode : lib path\r
-    ToolChainFamily     = property(_GetToolChainFamilies)    # toolcode : tool chain family\r
-    BuildOption         = property(_GetBuildOptions)    # toolcode : option\r
-    OutputFlag          = property(_GetOuputFlags)    # toolcode : output flag\r
-    IncludeFlag         = property(_GetIncludeFlags)    # toolcode : include flag\r
-    ToolOption          = property(_GetToolOptions)    # toolcode : tool option string\r
-\r
-    BuildCommand        = property(_GetBuildCommand)\r
-    BuildRule           = property(_GetBuildRule)\r
-    ModuleAutoGenList   = property(_GetModuleAutoGenList)\r
-    LibraryAutoGenList  = property(_GetLibraryAutoGenList)\r
-\r
-## ModuleAutoGen class\r
-#\r
-# This class encapsules the AutoGen behaviors for the build tools. In addition to\r
-# the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according\r
-# to the [depex] section in module's inf file.\r
-#\r
-class ModuleAutoGen(AutoGen):\r
-    ## The real constructor of ModuleAutoGen\r
-    #\r
-    #  This method is not supposed to be called by users of ModuleAutoGen. It's\r
-    #  only used by factory method __new__() to do real initialization work for an\r
-    #  object of ModuleAutoGen\r
-    #\r
-    #   @param      Workspace           EdkIIWorkspaceBuild object\r
-    #   @param      ModuleFile          The path of module file\r
-    #   @param      Target              Build target (DEBUG, RELEASE)\r
-    #   @param      Toolchain           Name of tool chain\r
-    #   @param      Arch                The arch the module supports\r
-    #   @param      PlatformFile        Platform meta-file\r
-    #\r
-    def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):\r
-        EdkLogger.verbose("\nAutoGen module [%s] [%s]" % (ModuleFile, Arch))\r
-\r
-        self.Workspace = Workspace\r
-        self.WorkspaceDir = Workspace.WorkspaceDir\r
-\r
-        self._MetaFile = str(ModuleFile)\r
-        self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)\r
-        # check if this module is employed by active platform\r
-        if not self.PlatformInfo.ValidModule(self._MetaFile):\r
-            EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \\r
-                              % (self._MetaFile, Arch))\r
-            return False\r
-\r
-        self.SourceDir = path.dirname(self._MetaFile)\r
-        self.FileBase, self.FileExt = path.splitext(path.basename(self._MetaFile))\r
-\r
-        self.ToolChain = Toolchain\r
-        self.ToolChainFamily = "MSFT"\r
-        self.BuildTarget = Target\r
-        self.Arch = Arch\r
-\r
-        self.IsMakeFileCreated = False\r
-        self.IsCodeFileCreated = False\r
-\r
-        self.BuildDatabase = self.Workspace.BuildDatabase\r
-\r
-        self._Module          = None\r
-        self._Name            = None\r
-        self._Guid            = None\r
-        self._Version         = None\r
-        self._ModuleType      = None\r
-        self._ComponentType   = None\r
-        self._PcdIsDriver     = None\r
-        self._AutoGenVersion  = None\r
-        self._LibraryFlag     = None\r
-        self._CustomMakefile  = None\r
-        self._Macro           = None\r
-\r
-        self._BuildDir        = None\r
-        self._OutputDir       = None\r
-        self._DebugDir        = None\r
-        self._MakeFileDir     = None\r
-\r
-        self._IncludePathList = None\r
-        self._AutoGenFileList = None\r
-        self._UnicodeFileList = None\r
-        self._SourceFileList  = None\r
-        self._ObjectFileList  = None\r
-        self._BinaryFileDict  = None\r
-\r
-        self._DependentPackageList    = None\r
-        self._DependentLibraryList    = None\r
-        self._LibraryAutoGenList      = None\r
-        self._DerivedPackageList      = None\r
-        self._PcdList                 = None\r
-        self._GuidList                = None\r
-        self._ProtocolList            = None\r
-        self._PpiList                 = None\r
-        self._DepexList               = None\r
-        self._BuildOption             = None\r
-\r
-        return True\r
-\r
-\r
-    ## Return the module build data object\r
-    def _GetModule(self):\r
-        if self._Module == None:\r
-            self._Module = self.Workspace.BuildDatabase[self._MetaFile, self.Arch]\r
-        return self._Module\r
-\r
-    ## Return the module name\r
-    def _GetBaseName(self):\r
-        return self.Module.BaseName\r
-\r
-    ## Return the module meta-file GUID\r
-    def _GetGuid(self):\r
-        return self.Module.Guid\r
-\r
-    ## Return the module version\r
-    def _GetVersion(self):\r
-        return self.Module.Version\r
-\r
-    ## Return the module type\r
-    def _GetModuleType(self):\r
-        return self.Module.ModuleType\r
-\r
-    ## Return the component type (for R8.x style of module)\r
-    def _GetComponentType(self):\r
-        return self.Module.ComponentType\r
-\r
-    ## Return the PCD_IS_DRIVER setting\r
-    def _GetPcdIsDriver(self):\r
-        return self.Module.PcdIsDriver\r
-\r
-    ## Return the autogen version, i.e. module meta-file version\r
-    def _GetAutoGenVersion(self):\r
-        return self.Module.AutoGenVersion\r
-\r
-    ## Check if the module is library or not\r
-    def _IsLibrary(self):\r
-        if self._LibraryFlag == None:\r
-            if self.Module.LibraryClass != None and self.Module.LibraryClass != []:\r
-                self._LibraryFlag = True\r
-            else:\r
-                self._LibraryFlag = False\r
-        return self._LibraryFlag\r
-\r
-    ## Return the directory to store intermediate files of the module\r
-    def _GetBuildDir(self):\r
-        if self._BuildDir == None:\r
-            self._BuildDir = path.join(\r
-                                    self.PlatformInfo.BuildDir,\r
-                                    self.Arch,\r
-                                    self.SourceDir,\r
-                                    self.FileBase\r
-                                    )\r
-        return self._BuildDir\r
-\r
-    ## Return the directory to store the intermediate object files of the mdoule\r
-    def _GetOutputDir(self):\r
-        if self._OutputDir == None:\r
-            self._OutputDir = path.join(self.BuildDir, "OUTPUT")\r
-        return self._OutputDir\r
-\r
-    ## Return the directory to store auto-gened source files of the mdoule\r
-    def _GetDebugDir(self):\r
-        if self._DebugDir == None:\r
-            self._DebugDir = path.join(self.BuildDir, "DEBUG")\r
-        return self._DebugDir\r
-\r
-    ## Return the path of custom file\r
-    def _GetCustomMakefile(self):\r
-        if self._CustomMakefile == None:\r
-            self._CustomMakefile = {}\r
-            for Type in self.Module.CustomMakefile:\r
-                MakeType = gMakeTypeMap[Type]\r
-                self._CustomMakefile[MakeType] = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])\r
-        return self._CustomMakefile\r
-\r
-    ## Return the directory of the makefile\r
-    #\r
-    #   @retval     string  The directory string of module's makefile\r
-    #\r
-    def _GetMakeFileDir(self):\r
-        return self.BuildDir\r
-\r
-    ## Return build command string\r
-    #\r
-    #   @retval     string  Build command string\r
-    #\r
-    def _GetBuildCommand(self):\r
-        return self.PlatformInfo.BuildCommand\r
-\r
-    ## Get object list of all packages the module and its dependent libraries belong to\r
-    #\r
-    #   @retval     list    The list of package object\r
-    #\r
-    def _GetDerivedPackageList(self):\r
-        PackageList = []\r
-        for M in [self.Module] + self.DependentLibraryList:\r
-            for Package in M.Packages:\r
-                if Package in PackageList:\r
-                    continue\r
-                PackageList.append(Package)\r
-        return PackageList\r
-\r
-    ## Merge dependency expression\r
-    #\r
-    #   @retval     list    The token list of the dependency expression after parsed\r
-    #\r
-    def _GetDepexTokenList(self):\r
-        if self._DepexList == None:\r
-            self._DepexList = self.Module.Depex\r
-            EdkLogger.verbose("DEPEX = %s" % self._DepexList)\r
-            #\r
-            # Append depex from dependent libraries\r
-            #\r
-            for Lib in self.DependentLibraryList:\r
-                if Lib.Depex != None and Lib.Depex != []:\r
-                    if self._DepexList != []:\r
-                        self._DepexList.append('AND')\r
-                    self._DepexList.append('(')\r
-                    self._DepexList.extend(Lib.Depex)\r
-                    self._DepexList.append(')')\r
-                    EdkLogger.verbose("DEPEX (+%s) = %s" % (Lib.BaseName, self._DepexList))\r
-\r
-            for I in range(0, len(self._DepexList)):\r
-                Token = self._DepexList[I]\r
-                if Token.endswith(".inf"):  # module file name\r
-                    ModuleFile = os.path.normpath(Token)\r
-                    self._DepexList[I] = self.BuildDatabase[ModuleFile].Guid\r
-        return self._DepexList\r
-\r
-    ## Return the list of macro in module\r
-    #\r
-    #   @retval     list    The list of macro defined in module file\r
-    #\r
-    def _GetMacroList(self):\r
-        return self.Module.Specification\r
-\r
-    ## Tool option for the module build\r
-    #\r
-    #   @param      PlatformInfo    The object of PlatformBuildInfo\r
-    #   @retval     dict            The dict containing valid options\r
-    #\r
-    def _GetModuleBuildOption(self):\r
-        if self._BuildOption == None:\r
-            self._BuildOption = self.PlatformInfo.ApplyBuildOption(self.Module)\r
-        return self._BuildOption\r
-\r
-    ## Return a list of files which can be built from source\r
-    #\r
-    #  What kind of files can be built is determined by build rules in\r
-    #  $(WORKSPACE)/Conf/build_rule.txt and toolchain family.\r
-    #\r
-    def _GetSourceFileList(self):\r
-        if self._SourceFileList != None:\r
-            return self._SourceFileList\r
-\r
-        self._SourceFileList = []\r
-        self._UnicodeFileList = []\r
-        # use toolchain family of CC as the primary toolchain family\r
-        if "CC" not in self.PlatformInfo.ToolChainFamily:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [CC] is not defined for %s [%s, %s]" \\r
-                             % (self.ToolChain, self.BuildTarget, self.Arch))\r
-        ToolChainFamily = self.PlatformInfo.ToolChainFamily["CC"]\r
-        BuildRule = self.PlatformInfo.BuildRule\r
-        for F in self.Module.Sources:\r
-            SourceFile = F.SourceFile\r
-            # match tool chain\r
-            if F.TagName != "" and F.TagName != self.ToolChain:\r
-                EdkLogger.verbose("The toolchain [%s] for processing file [%s] is found, "\r
-                                  "but [%s] is needed" % (F.TagName, F.SourceFile, self.ToolChain))\r
-                continue\r
-            # match tool chain family\r
-            if F.ToolChainFamily != "" and F.ToolChainFamily != ToolChainFamily:\r
-                EdkLogger.verbose("The file [%s] must be built by tools of [%s], "\r
-                                  "but current toolchain family is [%s]" % (SourceFile, F.ToolChainFamily, ToolChainFamily))\r
-                continue\r
-\r
-            # add the file path into search path list for file including\r
-            Dir = path.dirname(SourceFile)\r
-            if Dir != "":\r
-                Dir = path.join(self.WorkspaceDir, self.SourceDir, Dir)\r
-                if Dir not in self.IncludePathList:\r
-                    self.IncludePathList.insert(0, Dir)\r
-\r
-            # skip unknown file\r
-            Base, Ext = path.splitext(SourceFile)\r
-\r
-            # skip file which needs a tool having no matching toolchain family\r
-            FileType, RuleObject = BuildRule.Get(Ext, ToolChainFamily)\r
-            # unicode must be processed by AutoGen\r
-            if FileType == "Unicode-Text-File":\r
-                self._UnicodeFileList.append(os.path.join(self.WorkspaceDir, self.SourceDir, SourceFile))\r
-\r
-            # if there's dxs file, don't use content in [depex] section to generate .depex file\r
-            if FileType == "Dependency-Expression-File":\r
-                self._DepexList = []\r
-\r
-            # no command, no build\r
-            if RuleObject != None and RuleObject.CommandList == []:\r
-                RuleObject = None\r
-            if [SourceFile, FileType, RuleObject] not in self._SourceFileList:\r
-                self._SourceFileList.append([SourceFile, FileType, RuleObject])\r
-\r
-        return self._SourceFileList\r
-\r
-    ## Return the list of unicode files\r
-    def _GetUnicodeFileList(self):\r
-        if self._UnicodeFileList == None:\r
-            self._GetSourceFileList()\r
-        return self._UnicodeFileList\r
-\r
-    ## Return a list of files which can be built from binary\r
-    #\r
-    #  "Build" binary files are just to copy them to build directory.\r
-    #\r
-    #   @retval     list            The list of files which can be built later\r
-    #\r
-    def _GetBinaryFiles(self):\r
-        if self._BinaryFileDict == None:\r
-            self._BinaryFileDict = sdict()\r
-            for F in self.Module.Binaries:\r
-                if F.Target != '*' and F.Target != self.BuildTarget:\r
-                    continue\r
-                if F.FileType not in self._BinaryFileDict:\r
-                    self._BinaryFileDict[F.FileType] = []\r
-                self._BinaryFileDict[F.FileType].append(F.BinaryFile)\r
-        return self._BinaryFileDict\r
-\r
-    ## Get the list of package object the module depends on\r
-    #\r
-    #   @retval     list    The package object list\r
-    #\r
-    def _GetDependentPackageList(self):\r
-        return self.Module.Packages\r
-\r
-    ## Return the list of auto-generated code file\r
-    #\r
-    #   @retval     list        The list of auto-generated file\r
-    #\r
-    def _GetAutoGenFileList(self):\r
-        if self._AutoGenFileList == None:\r
-            self._AutoGenFileList = {}\r
-            AutoGenC = TemplateString()\r
-            AutoGenH = TemplateString()\r
-            GenC.CreateCode(self, AutoGenC, AutoGenH)\r
-            if str(AutoGenC) != "":\r
-                self._AutoGenFileList[gAutoGenCodeFileName] = AutoGenC\r
-            if str(AutoGenH) != "":\r
-                self._AutoGenFileList[gAutoGenHeaderFileName] = AutoGenH\r
-        return self._AutoGenFileList\r
-\r
-    ## Return the list of library modules explicitly or implicityly used by this module\r
-    def _GetLibraryList(self):\r
-        if self._DependentLibraryList == None:\r
-            # only merge library classes and PCD for non-library module\r
-            if self.IsLibrary:\r
-                self._DependentLibraryList = []\r
-            else:\r
-                if self.AutoGenVersion < 0x00010005:\r
-                    self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module)\r
-                else:\r
-                    self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)\r
-        return self._DependentLibraryList\r
-\r
-    ## Get the list of PCD\r
-    #\r
-    #   @retval     list                    The list of PCD\r
-    #\r
-    def _GetPcdList(self):\r
-        if self._PcdList == None:\r
-            if not self.IsLibrary:\r
-                # derive PCDs from libraries first\r
-                for Library in self.DependentLibraryList:\r
-                    for Key in Library.Pcds:\r
-                        if Key in self.Module.Pcds:\r
-                            continue\r
-                        self.Module.Pcds[Key] = copy.copy(Library.Pcds[Key])\r
-                # apply PCD settings from platform\r
-            self._PcdList = self.PlatformInfo.ApplyPcdSetting(self.Module)\r
-        return self._PcdList\r
-\r
-    ## Get the GUID value mapping\r
-    #\r
-    #   @retval     dict    The mapping between GUID cname and its value\r
-    #\r
-    def _GetGuidList(self):\r
-        if self._GuidList == None:\r
-            self._GuidList = self.Module.Guids\r
-            for Library in self.DependentLibraryList:\r
-                self._GuidList.update(Library.Guids)\r
-        return self._GuidList\r
-\r
-    ## Get the protocol value mapping\r
-    #\r
-    #   @retval     dict    The mapping between protocol cname and its value\r
-    #\r
-    def _GetProtocolList(self):\r
-        if self._ProtocolList == None:\r
-            self._ProtocolList = self.Module.Protocols\r
-            for Library in self.DependentLibraryList:\r
-                self._ProtocolList.update(Library.Protocols)\r
-        return self._ProtocolList\r
-\r
-    ## Get the PPI value mapping\r
-    #\r
-    #   @retval     dict    The mapping between PPI cname and its value\r
-    #\r
-    def _GetPpiList(self):\r
-        if self._PpiList == None:\r
-            self._PpiList = self.Module.Ppis\r
-            for Library in self.DependentLibraryList:\r
-                self._PpiList.update(Library.Ppis)\r
-        return self._PpiList\r
-\r
-    ## Get the list of include search path\r
-    #\r
-    #   @retval     list                    The list path\r
-    #\r
-    def _GetIncludePathList(self):\r
-        if self._IncludePathList == None:\r
-            self._IncludePathList = []\r
-            if self.AutoGenVersion < 0x00010005:\r
-                for Inc in self.Module.Includes:\r
-                    # '.' means "relative to module directory".\r
-                    if Inc[0] == ".":\r
-                        Inc = path.join(self.WorkspaceDir, self.SourceDir, Inc)\r
-                    else:\r
-                        Inc = path.join(self.WorkspaceDir, Inc)\r
-                    if Inc in self._IncludePathList:\r
-                        continue\r
-                    self._IncludePathList.append(Inc)\r
-                    # for r8 modules\r
-                    self._IncludePathList.append(path.join(Inc, self.Arch.capitalize()))\r
-                # r8 module needs to put DEBUG_DIR at the end search path and not to use SOURCE_DIR all the time\r
-                self._IncludePathList.append(self.DebugDir)\r
-            else:\r
-                self._IncludePathList.append(os.path.join(self.WorkspaceDir, self.SourceDir))\r
-                self._IncludePathList.append(self.DebugDir)\r
-\r
-            for Package in self.Module.Packages:\r
-                PackageDir = path.join(self.WorkspaceDir, path.dirname(str(Package)))\r
-                if PackageDir not in self._IncludePathList:\r
-                    self._IncludePathList.append(PackageDir)\r
-                for Inc in Package.Includes:\r
-                    Inc = path.join(PackageDir, Inc)\r
-                    if Inc not in self._IncludePathList:\r
-                        self._IncludePathList.append(Inc)\r
-        return self._IncludePathList\r
-\r
-    ## Create makefile for the module and its dependent libraries\r
-    #\r
-    #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of\r
-    #                                       dependent libraries will be created\r
-    #\r
-    def CreateMakeFile(self, CreateLibraryMakeFile=True):\r
-        if self.IsMakeFileCreated:\r
-            return\r
-\r
-        PlatformInfo = self.PlatformInfo\r
-        if not self.IsLibrary and CreateLibraryMakeFile:\r
-            for LibraryAutoGen in self.LibraryAutoGenList:\r
-                LibraryAutoGen.CreateMakeFile()\r
-\r
-        if len(self.CustomMakefile) == 0:\r
-            Makefile = GenMake.ModuleMakefile(self)\r
-        else:\r
-            Makefile = GenMake.CustomMakefile(self)\r
-        if Makefile.Generate():\r
-            EdkLogger.verbose("Generated makefile for module %s [%s]" %\r
-                           (self.Name, self.Arch))\r
-        else:\r
-            EdkLogger.verbose("Skipped the generation of makefile for module %s [%s]" %\r
-                              (self.Name, self.Arch))\r
-\r
-        self.IsMakeFileCreated = True\r
-\r
-    ## Create autogen code for the module and its dependent libraries\r
-    #\r
-    #   @param      CreateLibraryCodeFile   Flag indicating if or not the code of\r
-    #                                       dependent libraries will be created\r
-    #\r
-    def CreateCodeFile(self, CreateLibraryCodeFile=True):\r
-        if self.IsCodeFileCreated:\r
-            return\r
-\r
-        PlatformInfo = self.PlatformInfo\r
-        if not self.IsLibrary and CreateLibraryCodeFile:\r
-            for LibraryAutoGen in self.LibraryAutoGenList:\r
-                LibraryAutoGen.CreateCodeFile()\r
-\r
-        AutoGenList = []\r
-        IgoredAutoGenList = []\r
-        for File in self.AutoGenFileList:\r
-            if GenC.Generate(path.join(self.DebugDir, File), str(self.AutoGenFileList[File])):\r
-                AutoGenList.append(File)\r
-            else:\r
-                IgoredAutoGenList.append(File)\r
-\r
-        if self.DepexList != []:\r
-            Dpx = GenDepex.DependencyExpression(self.DepexList, self.ModuleType, True)\r
-            DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}\r
-\r
-            if Dpx.Generate(path.join(self.OutputDir, DpxFile)):\r
-                AutoGenList.append(DpxFile)\r
-            else:\r
-                IgoredAutoGenList.append(DpxFile)\r
-\r
-        if IgoredAutoGenList == []:\r
-            EdkLogger.verbose("Generated [%s] files for module %s [%s]" %\r
-                           (" ".join(AutoGenList), self.Name, self.Arch))\r
-        elif AutoGenList == []:\r
-            EdkLogger.verbose("Skipped the generation of [%s] files for module %s [%s]" %\r
-                           (" ".join(IgoredAutoGenList), self.Name, self.Arch))\r
-        else:\r
-            EdkLogger.verbose("Generated [%s] (skipped %s) files for module %s [%s]" %\r
-                           (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))\r
-\r
-        self.IsCodeFileCreated = True\r
-        return AutoGenList\r
-\r
-    ## Summarize the ModuleAutoGen objects of all libraries used by this module\r
-    def _GetLibraryAutoGenList(self):\r
-        if self._LibraryAutoGenList == None:\r
-            self._LibraryAutoGenList = []\r
-            for Library in self.DependentLibraryList:\r
-                La = ModuleAutoGen(\r
-                        self.Workspace,\r
-                        str(Library),\r
-                        self.BuildTarget,\r
-                        self.ToolChain,\r
-                        self.Arch,\r
-                        str(self.PlatformInfo)\r
-                        )\r
-                if La not in self._LibraryAutoGenList:\r
-                    self._LibraryAutoGenList.append(La)\r
-        return self._LibraryAutoGenList\r
-\r
-    ## Return build command string\r
-    #\r
-    #   @retval     string  Build command string\r
-    #\r
-    def _GetBuildCommand(self):\r
-        return self.PlatformInfo.BuildCommand\r
-\r
-\r
-    Module          = property(_GetModule)\r
-    Name            = property(_GetBaseName)\r
-    Guid            = property(_GetGuid)\r
-    Version         = property(_GetVersion)\r
-    ModuleType      = property(_GetModuleType)\r
-    ComponentType   = property(_GetComponentType)\r
-    PcdIsDriver     = property(_GetPcdIsDriver)\r
-    AutoGenVersion  = property(_GetAutoGenVersion)\r
-    Macro           = property(_GetMacroList)\r
-\r
-    IsLibrary       = property(_IsLibrary)\r
-\r
-    BuildDir        = property(_GetBuildDir)\r
-    OutputDir       = property(_GetOutputDir)\r
-    DebugDir        = property(_GetDebugDir)\r
-    MakeFileDir     = property(_GetMakeFileDir)\r
-    CustomMakefile  = property(_GetCustomMakefile)\r
-\r
-    IncludePathList = property(_GetIncludePathList)\r
-    AutoGenFileList = property(_GetAutoGenFileList)\r
-    UnicodeFileList = property(_GetUnicodeFileList)\r
-    SourceFileList  = property(_GetSourceFileList)\r
-    BinaryFileDict  = property(_GetBinaryFiles) # FileType : [File List]\r
-\r
-    DependentPackageList    = property(_GetDependentPackageList)\r
-    DependentLibraryList    = property(_GetLibraryList)\r
-    LibraryAutoGenList      = property(_GetLibraryAutoGenList)\r
-    DerivedPackageList      = property(_GetDerivedPackageList)\r
-\r
-    PcdList                 = property(_GetPcdList)\r
-    GuidList                = property(_GetGuidList)\r
-    ProtocolList            = property(_GetProtocolList)\r
-    PpiList                 = property(_GetPpiList)\r
-    DepexList               = property(_GetDepexTokenList)\r
-    BuildOption             = property(_GetModuleBuildOption)\r
-    BuildCommand            = property(_GetBuildCommand)\r
-\r
-# This acts like the main() function for the script, unless it is 'import'ed into another script.\r
-if __name__ == '__main__':\r
-    pass\r
-\r
+## @file
+# Generate AutoGen.h, AutoGen.c and *.depex files
+#
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. 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 sys
+import os
+import re
+import os.path as path
+import imp
+import copy
+from optparse import OptionParser
+from optparse import make_option
+
+import Common.EdkLogger
+import GenC
+import GenMake
+import GenDepex
+
+from StrGather import *
+from BuildEngine import *
+
+from Common.BuildToolError import *
+from Common.EdkIIWorkspaceBuild import *
+from Common.EdkIIWorkspace import *
+from Common.DataType import *
+from Common.Misc import *
+from Common.String import *
+from GenFds.FdfParser import *
+
+## Regular expression for splitting Dependency Expression stirng into tokens
+gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")
+
+## Mapping Makefile type
+gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}
+
+## Default output flag for all tools
+gDefaultOutputFlag = "-o "
+
+## Output flags for specific tools
+gOutputFlag = {
+    ("MSFT", "CC", "OUTPUT")      :   "/Fo",
+    ("MSFT", "SLINK", "OUTPUT")   :   "/OUT:",
+    ("MSFT", "DLINK", "OUTPUT")   :   "/OUT:",
+    ("MSFT", "ASMLINK", "OUTPUT") :   "/OUT:",
+    ("MSFT", "PCH", "OUTPUT")     :   "/Fp",
+    ("MSFT", "ASM", "OUTPUT")     :   "/Fo",
+
+    ("INTEL", "CC", "OUTPUT")          :   "/Fo",
+    ("INTEL", "SLINK", "OUTPUT")       :   "/OUT:",
+    ("INTEL", "DLINK", "OUTPUT")       :   "/OUT:",
+    ("INTEL", "ASMLINK", "OUTPUT")     :   "/OUT:",
+    ("INTEL", "PCH", "OUTPUT")         :   "/Fp",
+    ("INTEL", "ASM", "OUTPUT")         :   "/Fo",
+
+    ("GCC", "CC", "OUTPUT")        :   "-o ",
+    ("GCC", "SLINK", "OUTPUT")     :   "-cr ",
+    ("GCC", "DLINK", "OUTPUT")     :   "-o ",
+    ("GCC", "ASMLINK", "OUTPUT")   :   "-o ",
+    ("GCC", "PCH", "OUTPUT")       :   "-o ",
+    ("GCC", "ASM", "OUTPUT")       :   "-o ",
+}
+
+## Flag for include file search path
+gIncludeFlag = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I"}
+
+## Build rule configuration file
+gBuildRuleFile = 'Conf/build_rule.txt'
+
+## default file name for AutoGen
+gAutoGenCodeFileName = "AutoGen.c"
+gAutoGenHeaderFileName = "AutoGen.h"
+gAutoGenDepexFileName = "%(module_name)s.depex"
+
+## 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 self._MetaFile
+
+    ## "==" operator
+    def __eq__(self, Other):
+        return Other != None and self._MetaFile == str(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 explict 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  SkuId                   SKU id from command line
+    #
+    def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,
+              BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=[], Fvs=[], SkuId=''):
+        self._MetaFile      = str(ActivePlatform)
+        self.WorkspaceDir   = WorkspaceDir
+        self.Platform       = ActivePlatform
+        self.BuildTarget    = Target
+        self.ToolChain      = Toolchain
+        self.ArchList       = ArchList
+        self.SkuId          = SkuId
+
+        self.BuildDatabase  = MetaFileDb
+        self.TargetTxt      = BuildConfig
+        self.ToolDef        = ToolDefinition
+        self.FdfFile        = FlashDefinitionFile
+        self.FdTargetList   = Fds
+        self.FvTargetList   = Fvs
+        self.AutoGenObjectList = []
+
+        # there's many relative directory operations, so ...
+        os.chdir(self.WorkspaceDir)
+
+        # parse FDF file to get PCDs in it, if any
+        if self.FdfFile != None and self.FdfFile != '':
+            Fdf = FdfParser(os.path.join(self.WorkspaceDir, self.FdfFile))
+            Fdf.ParseFile()
+            PcdSet = Fdf.Profile.PcdDict
+            ModuleList = Fdf.Profile.InfList
+        else:
+            PcdSet = {}
+            ModuleList = []
+
+        # apply SKU and inject PCDs from Flash Definition file
+        for Arch in self.ArchList:
+            Platform = self.BuildDatabase[self._MetaFile, Arch]
+            Platform.SkuName = self.SkuId
+            for Name, Guid in PcdSet:
+                Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])
+
+            Pa = PlatformAutoGen(self, self._MetaFile, Target, Toolchain, Arch)
+            self.AutoGenObjectList.append(Pa)
+
+        self._BuildDir = None
+        self._FvDir = None
+        self._MakeFileDir = None
+        self._BuildCommand = None
+
+        return True
+
+    ## 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 _GetToolPaths(self):
+        return self.AutoGenObjectList[0].ToolPath
+
+    ## Return options of tools
+    def _GetToolOptions(self):
+        return self.AutoGenObjectList[0].ToolOption
+
+    ## 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
+
+    ## Create makefile for the platform and mdoules in it
+    #
+    #   @param      CreateDepsMakeFile      Flag indicating if the makefile for
+    #                                       modules will be created as well
+    #
+    def CreateMakeFile(self, CreateDepsMakeFile=False):
+        # create makefile for platform
+        Makefile = GenMake.TopLevelMakefile(self)
+        if Makefile.Generate():
+            EdkLogger.verbose("Generated makefile for platform [%s] %s\n" %
+                           (self._MetaFile, self.ArchList))
+        else:
+            EdkLogger.verbose("Skipped the generation of makefile for platform [%s] %s\n" %
+                           (self._MetaFile, self.ArchList))
+
+        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)
+
+    Name                = property(_GetName)
+    Guid                = property(_GetGuid)
+    Version             = property(_GetVersion)
+    OutputDir           = property(_GetOutputDir)
+
+    ToolPath            = property(_GetToolPaths)       # toolcode : tool path
+    ToolOption          = property(_GetToolOptions)     # toolcode : tool option string
+
+    BuildDir            = property(_GetBuildDir)
+    FvDir               = property(_GetFvDir)
+    MakeFileDir         = property(_GetMakeFileDir)
+    BuildCommand        = property(_GetBuildCommand)
+
+## AutoGen class for platform
+#
+#  PlatformAutoGen class will process the original information in platform
+#  file in order to generate makefile for platform.
+#
+class PlatformAutoGen(AutoGen):
+    ## 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       EdkIIWorkspaceBuild 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.verbose("\nAutoGen platform [%s] [%s]" % (PlatformFile, Arch))
+
+        self._MetaFile = str(PlatformFile)
+        self.Workspace = Workspace
+        self.WorkspaceDir = Workspace.WorkspaceDir
+        self.ToolChain = Toolchain
+        self.BuildTarget = Target
+        self.Arch = Arch
+        self.SourceDir = path.dirname(PlatformFile)
+        self.FdTargetList = self.Workspace.FdTargetList
+        self.FvTargetList = self.Workspace.FvTargetList
+
+        # 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._ToolPath = None          # toolcode : tool path
+        self._ToolDllPath = None       # toolcode : lib path
+        self._ToolStaticLib = None     # toolcode : lib path
+        self._ToolChainFamily = None   # toolcode : tool chain family
+        self._BuildOption = None       # toolcode : option
+        self._OutputFlag = None        # toolcode : output flag
+        self._IncludeFlag = None       # toolcode : include flag
+        self._ToolOption = None        # toolcode : tool option string
+        self._PackageList = None
+        self._ModuleAutoGenList  = None
+        self._LibraryAutoGenList = None
+        self._BuildCommand = None
+
+        # get the original module/package/platform objects
+        self.BuildDatabase = Workspace.BuildDatabase
+        return True
+
+    ## 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
+
+    ## 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)
+
+        # no need to create makefile for the platform more than once
+        if self.IsMakeFileCreated:
+            return
+
+        # create makefile for platform
+        Makefile = GenMake.PlatformMakefile(self)
+        if Makefile.Generate():
+            EdkLogger.verbose("Generated makefile for platform [%s] [%s]\n" %
+                           (self._MetaFile, self.Arch))
+        else:
+            EdkLogger.verbose("Skipped the generation of makefile for platform [%s] [%s]\n" %
+                           (self._MetaFile, self.Arch))
+        self.IsMakeFileCreated = True
+
+    ## Return the platform build data object
+    def _GetPlatform(self):
+        if self._Platform == None:
+            self._Platform = self.BuildDatabase[self._MetaFile, self.Arch]
+        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= path.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 = tuple()
+            if "MAKE" in self.ToolPath:
+                self._BuildCommand += (self.ToolPath["MAKE"],)
+                if "MAKE" in self.ToolOption:
+                    NewOption = self.ToolOption["MAKE"].strip()
+                    if NewOption != '':
+                      self._BuildCommand += (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):
+        ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary
+        ToolCodeList = self.Workspace.ToolDef.ToolsDefTxtDatabase["COMMAND_TYPE"]
+        self._ToolPath = {}
+        self._ToolDllPath = {}
+        self._ToolChainFamily = {}
+        self._ToolOption = {}
+        self._OutputFlag = {}
+        self._IncludeFlag = {}
+        for Tool in ToolCodeList:
+            KeyBaseString = "%s_%s_%s_%s" % (self.BuildTarget, self.ToolChain, self.Arch, Tool)
+
+            Key = "%s_PATH" % KeyBaseString
+            if Key not in ToolDefinition:
+                continue
+            Path = ToolDefinition[Key]
+
+            Key = "%s_FAMILY" % KeyBaseString
+            if Key in ToolDefinition:
+                Family = ToolDefinition[Key]
+            else:
+                Family = ""
+
+            Key = "%s_FLAGS" % KeyBaseString
+            if Key in ToolDefinition:
+                Option = ToolDefinition[Key]
+            else:
+                Option = ""
+
+            Key = "%s_DLL" % KeyBaseString
+            if Key in ToolDefinition:
+                Dll = ToolDefinition[Key]
+                # set the DLL path in system's PATH environment
+                os.environ["PATH"] = Dll + os.pathsep + os.environ["PATH"]
+            else:
+                Dll = ""
+
+            Key = KeyBaseString + "_OUTPUT"
+            if Key in ToolDefinition:
+                OutputFlag = ToolDefinition[Key]
+            elif (Family, Tool, "OUTPUT") in gOutputFlag:
+                OutputFlag = gOutputFlag[Family, Tool, "OUTPUT"]
+                if OutputFlag[0] == '"' and OutputFlag[-1] == '"':
+                    OutputFlag = OutputFlag[1:-1]
+            else:
+                OutputFlag = gDefaultOutputFlag
+
+            InputFlag = gIncludeFlag[Family]
+
+            self._ToolPath[Tool] = Path
+            self._ToolDllPath[Tool] = Dll
+            self._ToolChainFamily[Tool] = Family
+            self._ToolOption[Tool] = Option
+            self._OutputFlag[Tool] = OutputFlag
+            self._IncludeFlag[Tool] = InputFlag
+
+    ## Return the paths of tools
+    def _GetToolPaths(self):
+        if self._ToolPath == None:
+            self._GetToolDefinition()
+        return self._ToolPath
+
+    ## Return the dll paths of tools
+    def _GetToolDllPaths(self):
+        if self._ToolDllPath == None:
+            self._GetToolDefinition()
+        return self._ToolDllPath
+
+    ## Return the static libraries of tools
+    def _GetToolStaticLibs(self):
+        if self._ToolStaticLib == None:
+            self._GetToolDefinition()
+        return self._ToolStaticLib
+
+    ## Return the families of tools
+    def _GetToolChainFamilies(self):
+        if self._ToolChainFamily == None:
+            self._GetToolDefinition()
+        return self._ToolChainFamily
+
+    ## Return the build options specific to this platform
+    def _GetBuildOptions(self):
+        if self._BuildOption == None:
+            self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)
+        return self._BuildOption
+
+    ## Return the output flag of tools
+    def _GetOuputFlags(self):
+        if self._OutputFlag == None:
+            self._GetToolDefinition()
+        return self._OutputFlag
+
+    ## Return the include flags of tools
+    def _GetIncludeFlags(self):
+        if self._IncludeFlag == None:
+            self._GetToolDefinition()
+        return self._IncludeFlag
+
+    ## Return the default options of tools
+    def _GetToolOptions(self):
+        if self._ToolOption == None:
+            self._GetToolDefinition()
+        return self._ToolOption
+
+    ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt
+    #
+    #   @retval     BuildRule object
+    #
+    def _GetBuildRule(self):
+        if self._BuildRule == None:
+            BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]
+            if BuildRuleFile in [None, '']:
+                BuildRuleFile = gBuildRuleFile
+            self._BuildRule = BuildRule(BuildRuleFile)
+        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)
+        return self._PackageList
+
+    ## Collect dynamic PCDs
+    #
+    #  Gather dynamic PCDs list from each module and their settings from platform
+    #
+    def _GetPcdList(self):
+        self._NonDynamicPcdList = []
+        self._DynamicPcdList = []
+
+        # for gathering error information
+        NotFoundPcdList = set()
+        NoDatumTypePcdList = set()
+
+        self._GuidValue = {}
+        for F in self.Platform.Modules:
+            M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self._MetaFile)
+            #GuidValue.update(M.Guids)
+            for PcdFromModule in M.PcdList:
+                # check if the setting of the PCD is found in platform
+                #if not PcdFromModule.IsOverrided:
+                #    NotFoundPcdList.add("%s [%s]" % (" | ".join(Key), F))
+                #    continue
+
+                # make sure that the "VOID*" kind of datum has MaxDatumSize set
+                if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize == None:
+                    NoDatumTypePcdList.add("%s [%s]" % (" | ".join(Key), F))
+
+                if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:
+                    # for autogen code purpose
+                    if M.ModuleType in ["PEIM", "PEI_CORE"]:
+                        PcdFromModule.Phase = "PEI"
+                    if PcdFromModule not in self._DynamicPcdList:
+                        self._DynamicPcdList.append(PcdFromModule)
+                elif PcdFromModule not in self._NonDynamicPcdList:
+                    self._NonDynamicPcdList.append(PcdFromModule)
+
+        # print out error information and break the build, if error found
+        if len(NoDatumTypePcdList) > 0:
+            NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)
+            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "PCD setting error",
+                            ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
+                                      % NoDatumTypePcdListString)
+
+    ## Get list of non-dynamic PCDs
+    def _GetNonDynamicPcdList(self):
+        if self._NonDynamicPcdList == None:
+            self._GetPcdList()
+        return self._NonDynamicPcdList
+
+    ## Get list of dynamic PCDs
+    def _GetDynamicPcdList(self):
+        if self._DynamicPcdList == None:
+            self._GetPcdList()
+        return self._DynamicPcdList
+
+    ## Generate Token Number for all PCD
+    def _GetPcdTokenNumbers(self):
+        if self._PcdTokenNumber == None:
+            self._PcdTokenNumber = sdict()
+            TokenNumber = 1
+            for Pcd in self.DynamicPcdList:
+                if Pcd.Phase == "PEI":
+                    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":
+                    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)
+
+    ## 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
+
+    ## 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):
+        ModuleType = Module.ModuleType
+        # apply library instances from platform
+        for LibraryClass in Module.LibraryClasses:
+            LibraryInstance = self.Platform.LibraryClasses[LibraryClass, ModuleType]
+            if LibraryInstance == None:
+                continue
+            Module.LibraryClasses[LibraryClass] = LibraryInstance
+
+        # override library instances with module specific setting
+        PlatformModule = self.Platform.Modules[str(Module)]
+        for LibraryClass in PlatformModule.LibraryClasses:
+            Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]
+
+        # R9 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:
+                LibraryPath = M.LibraryClasses[LibraryClassName]
+                if LibraryPath == None or LibraryPath == "":
+                    LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]
+                    if LibraryPath == None and LibraryClassName not in LibraryInstance:
+                        LibraryInstance[LibraryClassName] = None
+                        continue
+                if LibraryClassName not in LibraryInstance:
+                    LibraryModule = self.BuildDatabase[LibraryPath, self.Arch]
+                    # for those forced library instance (NULL library), add a fake library class
+                    if LibraryClassName.startswith("NULL"):
+                        LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))
+                    elif ModuleType not in LibraryModule.LibraryClass[0].SupModList:
+                        EdkLogger.error("build", OPTION_MISSING,
+                                        "Module type [%s] is not supported by library instance [%s]" \
+                                        % (ModuleType, LibraryPath), File=self._MetaFile,
+                                        ExtraData="\tconsumed 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]
+            if M == None:
+                EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
+                                "Library instance of library class [%s] is not found" % LibraryClassName,
+                                File=self._MetaFile, ExtraData="consumed by [%s] [%s]" % (str(Module), self.Arch))
+            LibraryList.append(M)
+            #
+            # check if there're library classes
+            #
+            #for Lc in M.LibraryClass:
+            #    if Lc.SupModList != None and ModuleType not in Lc.SupModList:
+            #        EdkLogger.error("build", OPTION_MISSING,
+            #                        "Module type [%s] is not supported by library instance [%s]" % (ModuleType, str(M)),
+            #                        File=self._MetaFile, ExtraData="\tconsumed by [%s]" % str(Module))
+
+                #if Lc.LibraryClass in LibraryInstance and str(M) != str(LibraryInstance[Lc.LibraryClass]):
+                #    EdkLogger.error("build", OPTION_CONFLICT,
+                #                    "More than one library instance found for library class [%s] in module [%s]" % (Lc.LibraryClass, str(Module)),
+                #                    ExtraData="\t%s\n\t%s" % (LibraryInstance[Lc.LibraryClass], str(M))
+                #                    )
+            if ConsumedByList[M] == []:
+                Q.insert(0, 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
+        #
+        if FromPcd != None:
+            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:
+                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, ToPcd.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
+
+        if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:
+            EdkLogger.verbose("No MaxDatumSize specified for PCD %s.%s" \
+                              % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
+            Value = ToPcd.DefaultValue
+            if Value[0] == 'L':
+                ToPcd.MaxDatumSize = str(len(Value) * 2)
+            elif Value[0] == '{':
+                ToPcd.MaxDatumSize = str(len(Value.split(',')))
+            else:
+                ToPcd.MaxDatumSize = str(len(Value))
+
+        # 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], '', '', '', '', '', 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):
+        # for each PCD in module
+        for Name,Guid in Module.Pcds:
+            PcdInModule = Module.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)
+                if Sku.VariableGuidValue == None:
+                    PackageList = '\t' + "\n\t".join([str(P) for P in Module.Packages])
+                    EdkLogger.error(
+                                'build',
+                                RESOURCE_NOT_AVAILABLE,
+                                "Value of [%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 Module.Pcds:
+                    self._OverridePcd(Module.Pcds[Key], PlatformModule.Pcds[Key], Module)
+        return Module.Pcds.values()
+
+    ## Resolve library names to library modules
+    #
+    # (for R8.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 R8 modules
+        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:
+                    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
+
+    ## Expand * in build option key
+    #
+    #   @param  Options     Options to be expanded
+    #
+    #   @retval options     Options expanded
+    #
+    def _ExpandBuildOption(self, Options):
+        BuildOptions = {}
+        for Key in Options:
+            Family = Key[0]
+            Target, Tag, Arch, Tool, Attr = Key[1].split("_")
+            # if no tool defined for the option, skip it
+            if Tool not in self.ToolPath:
+                continue
+            # if tool chain family doesn't match, skip it
+            if Family != None and Family != "" and Family != self.ToolChainFamily[Tool]:
+                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] = Options[Key]
+                        else:
+                            # append options for the same tool
+                            BuildOptions[Tool] += " " + 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):
+        PlatformOptions = self.BuildOption
+        ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)
+        if Module in self.Platform.Modules:
+            PlatformModule = self.Platform.Modules[str(Module)]
+            PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)
+        else:
+            PlatformModuleOptions = {}
+
+        BuildOptions = {}
+        # for those tools that have no option in module file, give it a empty string
+        for Tool in self.Workspace.ToolPath:
+            if Tool in self.ToolOption and Module.ModuleType != 'USER_DEFINED':
+                BuildOptions[Tool] = self.ToolOption[Tool]
+            else:
+                BuildOptions[Tool] = ''
+            if Tool in ModuleOptions:
+                BuildOptions[Tool] += " " + ModuleOptions[Tool]
+            if Tool in PlatformOptions:
+                BuildOptions[Tool] += " " + PlatformOptions[Tool]
+            if Tool in PlatformModuleOptions:
+                BuildOptions[Tool] += " " + PlatformModuleOptions[Tool]
+        return BuildOptions
+
+    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), ...]
+    PackageList         = property(_GetPackageList)
+
+    ToolPath            = property(_GetToolPaths)    # toolcode : tool path
+    ToolDllPath         = property(_GetToolDllPaths)    # toolcode : lib path
+    ToolStaticLib       = property(_GetToolStaticLibs)    # toolcode : lib path
+    ToolChainFamily     = property(_GetToolChainFamilies)    # toolcode : tool chain family
+    BuildOption         = property(_GetBuildOptions)    # toolcode : option
+    OutputFlag          = property(_GetOuputFlags)    # toolcode : output flag
+    IncludeFlag         = property(_GetIncludeFlags)    # toolcode : include flag
+    ToolOption          = property(_GetToolOptions)    # toolcode : tool option string
+
+    BuildCommand        = property(_GetBuildCommand)
+    BuildRule           = property(_GetBuildRule)
+    ModuleAutoGenList   = property(_GetModuleAutoGenList)
+    LibraryAutoGenList  = property(_GetLibraryAutoGenList)
+
+## 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):
+    ## 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.verbose("\nAutoGen module [%s] [%s]" % (ModuleFile, Arch))
+
+        self.Workspace = Workspace
+        self.WorkspaceDir = Workspace.WorkspaceDir
+
+        self._MetaFile = str(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 = path.dirname(self._MetaFile)
+        self.FileBase, self.FileExt = path.splitext(path.basename(self._MetaFile))
+
+        self.ToolChain = Toolchain
+        self.ToolChainFamily = "MSFT"
+        self.BuildTarget = Target
+        self.Arch = Arch
+
+        self.IsMakeFileCreated = False
+        self.IsCodeFileCreated = False
+
+        self.BuildDatabase = self.Workspace.BuildDatabase
+
+        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._AutoGenFileList = None
+        self._UnicodeFileList = None
+        self._SourceFileList  = None
+        self._ObjectFileList  = None
+        self._BinaryFileDict  = None
+
+        self._DependentPackageList    = None
+        self._DependentLibraryList    = None
+        self._LibraryAutoGenList      = None
+        self._DerivedPackageList      = None
+        self._PcdList                 = None
+        self._GuidList                = None
+        self._ProtocolList            = None
+        self._PpiList                 = None
+        self._DepexList               = None
+        self._BuildOption             = None
+
+        return True
+
+
+    ## Return the module build data object
+    def _GetModule(self):
+        if self._Module == None:
+            self._Module = self.Workspace.BuildDatabase[self._MetaFile, self.Arch]
+        return self._Module
+
+    ## Return the module name
+    def _GetBaseName(self):
+        return self.Module.BaseName
+
+    ## Return the module meta-file GUID
+    def _GetGuid(self):
+        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 R8.x style of module)
+    def _GetComponentType(self):
+        return self.Module.ComponentType
+
+    ## 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
+
+    ## 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.FileBase
+                                    )
+        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")
+        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")
+        return self._DebugDir
+
+    ## Return the path of custom file
+    def _GetCustomMakefile(self):
+        if self._CustomMakefile == None:
+            self._CustomMakefile = {}
+            for Type in self.Module.CustomMakefile:
+                MakeType = gMakeTypeMap[Type]
+                self._CustomMakefile[MakeType] = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
+        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
+
+    ## Merge dependency expression
+    #
+    #   @retval     list    The token list of the dependency expression after parsed
+    #
+    def _GetDepexTokenList(self):
+        if self._DepexList == None:
+            self._DepexList = self.Module.Depex
+            EdkLogger.verbose("DEPEX = %s" % self._DepexList)
+            #
+            # Append depex from dependent libraries
+            #
+            for Lib in self.DependentLibraryList:
+                if Lib.Depex != None and Lib.Depex != []:
+                    if self._DepexList != []:
+                        self._DepexList.append('AND')
+                    self._DepexList.append('(')
+                    self._DepexList.extend(Lib.Depex)
+                    self._DepexList.append(')')
+                    EdkLogger.verbose("DEPEX (+%s) = %s" % (Lib.BaseName, self._DepexList))
+
+            for I in range(0, len(self._DepexList)):
+                Token = self._DepexList[I]
+                if Token.endswith(".inf"):  # module file name
+                    ModuleFile = os.path.normpath(Token)
+                    self._DepexList[I] = self.BuildDatabase[ModuleFile].Guid
+        return self._DepexList
+
+    ## Return the list of macro in module
+    #
+    #   @retval     list    The list of macro defined in module file
+    #
+    def _GetMacroList(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.PlatformInfo.ApplyBuildOption(self.Module)
+        return self._BuildOption
+
+    ## Return a list of files which can be built from source
+    #
+    #  What kind of files can be built is determined by build rules in
+    #  $(WORKSPACE)/Conf/build_rule.txt and toolchain family.
+    #
+    def _GetSourceFileList(self):
+        if self._SourceFileList != None:
+            return self._SourceFileList
+
+        self._SourceFileList = []
+        self._UnicodeFileList = []
+        # use toolchain family of CC as the primary toolchain family
+        if "CC" not in self.PlatformInfo.ToolChainFamily:
+            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [CC] is not defined for %s [%s, %s]" \
+                             % (self.ToolChain, self.BuildTarget, self.Arch))
+        ToolChainFamily = self.PlatformInfo.ToolChainFamily["CC"]
+        BuildRule = self.PlatformInfo.BuildRule
+        for F in self.Module.Sources:
+            SourceFile = F.SourceFile
+            # match tool chain
+            if F.TagName != "" and F.TagName != self.ToolChain:
+                EdkLogger.verbose("The toolchain [%s] for processing file [%s] is found, "
+                                  "but [%s] is needed" % (F.TagName, F.SourceFile, self.ToolChain))
+                continue
+            # match tool chain family
+            if F.ToolChainFamily != "" and F.ToolChainFamily != ToolChainFamily:
+                EdkLogger.verbose("The file [%s] must be built by tools of [%s], "
+                                  "but current toolchain family is [%s]" % (SourceFile, F.ToolChainFamily, ToolChainFamily))
+                continue
+
+            # add the file path into search path list for file including
+            Dir = path.dirname(SourceFile)
+            if Dir != "":
+                Dir = path.join(self.WorkspaceDir, self.SourceDir, Dir)
+                if Dir not in self.IncludePathList:
+                    self.IncludePathList.insert(0, Dir)
+
+            # skip unknown file
+            Base, Ext = path.splitext(SourceFile)
+
+            # skip file which needs a tool having no matching toolchain family
+            FileType, RuleObject = BuildRule.Get(Ext, ToolChainFamily)
+            # unicode must be processed by AutoGen
+            if FileType == "Unicode-Text-File":
+                self._UnicodeFileList.append(os.path.join(self.WorkspaceDir, self.SourceDir, SourceFile))
+
+            # if there's dxs file, don't use content in [depex] section to generate .depex file
+            if FileType == "Dependency-Expression-File":
+                self._DepexList = []
+
+            # no command, no build
+            if RuleObject != None and RuleObject.CommandList == []:
+                RuleObject = None
+            if [SourceFile, FileType, RuleObject] not in self._SourceFileList:
+                self._SourceFileList.append([SourceFile, FileType, RuleObject])
+
+        return self._SourceFileList
+
+    ## Return the list of unicode files
+    def _GetUnicodeFileList(self):
+        if self._UnicodeFileList == None:
+            self._GetSourceFileList()
+        return self._UnicodeFileList
+
+    ## 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._BinaryFileDict == None:
+            self._BinaryFileDict = sdict()
+            for F in self.Module.Binaries:
+                if F.Target != '*' and F.Target != self.BuildTarget:
+                    continue
+                if F.FileType not in self._BinaryFileDict:
+                    self._BinaryFileDict[F.FileType] = []
+                self._BinaryFileDict[F.FileType].append(F.BinaryFile)
+        return self._BinaryFileDict
+
+    ## 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):
+        if self._AutoGenFileList == None:
+            self._AutoGenFileList = {}
+            AutoGenC = TemplateString()
+            AutoGenH = TemplateString()
+            GenC.CreateCode(self, AutoGenC, AutoGenH)
+            if str(AutoGenC) != "":
+                self._AutoGenFileList[gAutoGenCodeFileName] = AutoGenC
+            if str(AutoGenH) != "":
+                self._AutoGenFileList[gAutoGenHeaderFileName] = AutoGenH
+        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
+
+    ## Get the list of PCD
+    #
+    #   @retval     list                    The list of PCD
+    #
+    def _GetPcdList(self):
+        if self._PcdList == None:
+            if not self.IsLibrary:
+                # derive PCDs from libraries first
+                for Library in self.DependentLibraryList:
+                    for Key in Library.Pcds:
+                        if Key in self.Module.Pcds:
+                            continue
+                        self.Module.Pcds[Key] = copy.copy(Library.Pcds[Key])
+                # apply PCD settings from platform
+            self._PcdList = self.PlatformInfo.ApplyPcdSetting(self.Module)
+        return self._PcdList
+
+    ## Get the GUID value mapping
+    #
+    #   @retval     dict    The mapping between GUID cname and its value
+    #
+    def _GetGuidList(self):
+        if self._GuidList == None:
+            self._GuidList = self.Module.Guids
+            for Library in self.DependentLibraryList:
+                self._GuidList.update(Library.Guids)
+        return self._GuidList
+
+    ## Get the protocol value mapping
+    #
+    #   @retval     dict    The mapping between protocol cname and its value
+    #
+    def _GetProtocolList(self):
+        if self._ProtocolList == None:
+            self._ProtocolList = self.Module.Protocols
+            for Library in self.DependentLibraryList:
+                self._ProtocolList.update(Library.Protocols)
+        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 = self.Module.Ppis
+            for Library in self.DependentLibraryList:
+                self._PpiList.update(Library.Ppis)
+        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:
+                    # '.' means "relative to module directory".
+                    if Inc[0] == ".":
+                        Inc = path.join(self.WorkspaceDir, self.SourceDir, Inc)
+                    else:
+                        Inc = path.join(self.WorkspaceDir, Inc)
+                    if Inc in self._IncludePathList:
+                        continue
+                    self._IncludePathList.append(Inc)
+                    # for r8 modules
+                    self._IncludePathList.append(path.join(Inc, self.Arch.capitalize()))
+                # r8 module needs to put DEBUG_DIR at the end search path and not to use SOURCE_DIR all the time
+                self._IncludePathList.append(self.DebugDir)
+            else:
+                self._IncludePathList.append(os.path.join(self.WorkspaceDir, self.SourceDir))
+                self._IncludePathList.append(self.DebugDir)
+
+            for Package in self.Module.Packages:
+                PackageDir = path.join(self.WorkspaceDir, path.dirname(str(Package)))
+                if PackageDir not in self._IncludePathList:
+                    self._IncludePathList.append(PackageDir)
+                for Inc in Package.Includes:
+                    Inc = path.join(PackageDir, Inc)
+                    if Inc not in self._IncludePathList:
+                        self._IncludePathList.append(Inc)
+        return self._IncludePathList
+
+    ## 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):
+        if self.IsMakeFileCreated:
+            return
+
+        PlatformInfo = self.PlatformInfo
+        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.verbose("Generated makefile for module %s [%s]" %
+                           (self.Name, self.Arch))
+        else:
+            EdkLogger.verbose("Skipped the generation of makefile for module %s [%s]" %
+                              (self.Name, self.Arch))
+
+        self.IsMakeFileCreated = True
+
+    ## 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
+
+        PlatformInfo = self.PlatformInfo
+        if not self.IsLibrary and CreateLibraryCodeFile:
+            for LibraryAutoGen in self.LibraryAutoGenList:
+                LibraryAutoGen.CreateCodeFile()
+
+        AutoGenList = []
+        IgoredAutoGenList = []
+        for File in self.AutoGenFileList:
+            if GenC.Generate(path.join(self.DebugDir, File), str(self.AutoGenFileList[File])):
+                AutoGenList.append(File)
+            else:
+                IgoredAutoGenList.append(File)
+
+        if self.DepexList != []:
+            Dpx = GenDepex.DependencyExpression(self.DepexList, self.ModuleType, True)
+            DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}
+
+            if Dpx.Generate(path.join(self.OutputDir, DpxFile)):
+                AutoGenList.append(DpxFile)
+            else:
+                IgoredAutoGenList.append(DpxFile)
+
+        if IgoredAutoGenList == []:
+            EdkLogger.verbose("Generated [%s] files for module %s [%s]" %
+                           (" ".join(AutoGenList), self.Name, self.Arch))
+        elif AutoGenList == []:
+            EdkLogger.verbose("Skipped the generation of [%s] files for module %s [%s]" %
+                           (" ".join(IgoredAutoGenList), self.Name, self.Arch))
+        else:
+            EdkLogger.verbose("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,
+                        str(Library),
+                        self.BuildTarget,
+                        self.ToolChain,
+                        self.Arch,
+                        str(self.PlatformInfo)
+                        )
+                if La not in self._LibraryAutoGenList:
+                    self._LibraryAutoGenList.append(La)
+        return self._LibraryAutoGenList
+
+    ## Return build command string
+    #
+    #   @retval     string  Build command string
+    #
+    def _GetBuildCommand(self):
+        return self.PlatformInfo.BuildCommand
+
+
+    Module          = property(_GetModule)
+    Name            = property(_GetBaseName)
+    Guid            = property(_GetGuid)
+    Version         = property(_GetVersion)
+    ModuleType      = property(_GetModuleType)
+    ComponentType   = property(_GetComponentType)
+    PcdIsDriver     = property(_GetPcdIsDriver)
+    AutoGenVersion  = property(_GetAutoGenVersion)
+    Macro           = property(_GetMacroList)
+
+    IsLibrary       = property(_IsLibrary)
+
+    BuildDir        = property(_GetBuildDir)
+    OutputDir       = property(_GetOutputDir)
+    DebugDir        = property(_GetDebugDir)
+    MakeFileDir     = property(_GetMakeFileDir)
+    CustomMakefile  = property(_GetCustomMakefile)
+
+    IncludePathList = property(_GetIncludePathList)
+    AutoGenFileList = property(_GetAutoGenFileList)
+    UnicodeFileList = property(_GetUnicodeFileList)
+    SourceFileList  = property(_GetSourceFileList)
+    BinaryFileDict  = property(_GetBinaryFiles) # FileType : [File List]
+
+    DependentPackageList    = property(_GetDependentPackageList)
+    DependentLibraryList    = property(_GetLibraryList)
+    LibraryAutoGenList      = property(_GetLibraryAutoGenList)
+    DerivedPackageList      = property(_GetDerivedPackageList)
+
+    PcdList                 = property(_GetPcdList)
+    GuidList                = property(_GetGuidList)
+    ProtocolList            = property(_GetProtocolList)
+    PpiList                 = property(_GetPpiList)
+    DepexList               = property(_GetDepexTokenList)
+    BuildOption             = property(_GetModuleBuildOption)
+    BuildCommand            = property(_GetBuildCommand)
+
+# This acts like the main() function for the script, unless it is 'import'ed into another script.
+if __name__ == '__main__':
+    pass
+