Changed the code to be able to bypass AutoGen completely
authorjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Sat, 19 Apr 2008 15:41:04 +0000 (15:41 +0000)
committerjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Sat, 19 Apr 2008 15:41:04 +0000 (15:41 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1160 7335b38e-4728-0410-8992-fb3ffe349368

12 files changed:
Source/Python/AutoGen/AutoGen.py
Source/Python/AutoGen/GenC.py
Source/Python/AutoGen/GenMake.py
Source/Python/Common/DataType.py
Source/Python/Common/Misc.py
Source/Python/CommonDataClass/CommonClass.py
Source/Python/CommonDataClass/DataClass.py
Source/Python/Workspace/BuildClassObject.py
Source/Python/Workspace/MetaFileParser.py
Source/Python/Workspace/MetaFileTable.py
Source/Python/Workspace/WorkspaceDatabase.py
Source/Python/build/build.py

index 7b99e26..ff964ac 100755 (executable)
@@ -26,7 +26,6 @@ import GenC
 import GenMake\r
 import GenDepex\r
 \r
-from BuildInfo import *\r
 from StrGather import *\r
 from BuildEngine import *\r
 \r
@@ -36,6 +35,7 @@ from Common.EdkIIWorkspace import *
 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
@@ -81,15 +81,198 @@ gAutoGenCodeFileName = "AutoGen.c"
 gAutoGenHeaderFileName = "AutoGen.h"\r
 gAutoGenDepexFileName = "%(module_name)s.depex"\r
 \r
+class AutoGen(object):\r
+    # database to maintain the objects of PlatformAutoGen\r
+    _CACHE_ = {}    # (platform file, BuildTarget, ToolChain) : {ARCH : AutoGen object}\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
+            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
+class WorkspaceAutoGen(AutoGen):\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 operation, 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
+            #for M in ModuleList:\r
+            #    Platform.AddModule(M)\r
+\r
+        self._BuildDir = None\r
+        self._FvDir = None\r
+        self._MakeFileDir = None\r
+        self._BuildCommand = None\r
+\r
+        return True\r
+\r
+    def _GetFvDir(self):\r
+        if self._FvDir == None:\r
+            self._FvDir = path.join(self.BuildDir, 'FV')\r
+        return self._FvDir\r
+            \r
+    def _GetBuildDir(self):\r
+        return self.AutoGenObjectList[0].BuildDir\r
+\r
+    def _GetOutputDir(self):\r
+        return self.Platform.OutputDirectory\r
+\r
+    def _GetName(self):\r
+        return self.Platform.PlatformName\r
+\r
+    def _GetGuid(self):\r
+        return self.Platform.Guid\r
+\r
+    def _GetVersion(self):\r
+        return self.Platform.Version\r
+\r
+    def _GetToolPaths(self):\r
+        return self.AutoGenObjectList[0].ToolPath\r
+\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      CreateLibraryCodeFile   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      CreateModuleCodeFile    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 re-organize the original information in platform\r
 #  file in order to generate makefile for platform.\r
 #\r
-class PlatformAutoGen:\r
-    # database to maintain the objects of PlatformAutoGen\r
-    _Database = {}    # (platform file, BuildTarget, ToolChain) : PlatformAutoGen object\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
@@ -102,179 +285,169 @@ class PlatformAutoGen:
     #   @param      Toolchain       Name of tool chain\r
     #   @param      ArchList        List of arch the platform supports\r
     #\r
-    def _Init(self, Workspace, PlatformFile, Target, Toolchain, ArchList):\r
-        self.PlatformFile = str(PlatformFile)\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.ArchList = ArchList\r
-\r
-        EdkLogger.verbose("\nAutoGen platform [%s] [%s]" % (self.PlatformFile, " ".join(self.ArchList)))\r
-\r
-        # get the original module/package/platform objects\r
-        self.ModuleDatabase = {}\r
-        for a in Workspace.Build:\r
-            self.ModuleDatabase[a] = Workspace.Build[a].ModuleDatabase\r
-\r
-        self.PackageDatabase = {}\r
-        for a in Workspace.Build:\r
-            self.PackageDatabase[a] = Workspace.Build[a].PackageDatabase\r
-\r
-        self.PlatformDatabase = {}\r
-        for a in Workspace.Build:\r
-            self.PlatformDatabase[a] = Workspace.Build[a].PlatformDatabase\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
+        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
-        #\r
-        # collect build information for the platform\r
-        #\r
-        self.BuildInfo = {}     # arch : PlatformBuildInfo Object\r
-        self.Platform = {}\r
-\r
-        for Arch in self.ArchList:\r
-            if Arch not in self.PlatformDatabase or self.PlatformFile not in self.PlatformDatabase[Arch]:\r
-                EdkLogger.error("AutoGen", AUTOGEN_ERROR,\r
-                                "[%s] is not the active platform, or [%s] is not supported by the active platform!"\r
-                                % (PlatformFile, Arch))\r
-            Platform = self.PlatformDatabase[Arch][PlatformFile]\r
-            self.Platform[Arch] = Platform\r
-            self.BuildInfo[Arch] = self.CollectBuildInfo(Platform, Arch)\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.PlatformFile)\r
+        # get the original module/package/platform objects\r
+        self.BuildDatabase = Workspace.BuildDatabase\r
+        return True\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
+    ## Create autogen code for platform and modules\r
     #\r
-    def __str__(self):\r
-        return self.PlatformFile\r
-\r
-    ## Factory method to create a PlatformAutoGen object\r
+    #  Since there's no autogen code for platform, this method will do nothing\r
+    #  if CreateModuleCodeFile is set to False.\r
     #\r
-    #   This method will check if an object of PlatformAutoGen has been created\r
-    #   for given platform. And if true, just return it. Otherwise it will create\r
-    #   a new PlatformAutoGen. That means there will be only one PlatformAutoGen\r
-    #   object for the same platform.\r
+    #   @param      CreateModuleCodeFile    Flag indicating if creating module's\r
+    #                                       autogen code file or not\r
     #\r
-    #   @param      Workspace           EdkIIWorkspaceBuild object\r
-    #   @param      Platform            Platform file (DSC file)\r
-    #   @param      Target              Build target (DEBUG, RELEASE)\r
-    #   @param      Toolchain           Name of tool chain\r
-    #   @param      ArchList            List of arch the platform supports\r
-    #   @param      ModuleAutoGenFlag   Flag indicating if creating ModuleAutoGen\r
-    #                                   objects for mdoules in the platform or not\r
-    #\r
-    #   @retval     PlatformAutoGen object\r
-    #\r
-    @staticmethod\r
-    def New(Workspace, Platform, Target, Toolchain, ArchList, ModuleAutoGenFlag=False):\r
-        # check if the object for the platform has been created\r
-        Key = (Platform, Target, Toolchain)\r
-        if Key not in PlatformAutoGen._Database:\r
-            if ArchList == None or ArchList == []:\r
-                return None\r
-            AutoGenObject = PlatformAutoGen()\r
-            AutoGenObject._Init(Workspace, Platform, Target, Toolchain, ArchList)\r
-            PlatformAutoGen._Database[Key] = AutoGenObject\r
-        else:\r
-            AutoGenObject = PlatformAutoGen._Database[Key]\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
-        # create ModuleAutoGen objects for modules in the platform\r
-        if ModuleAutoGenFlag:\r
-            AutoGenObject.CreateModuleAutoGen()\r
+        for Ma in self.ModuleAutoGenList:\r
+            Ma.CreateCodeFile(True)\r
 \r
-        return AutoGenObject\r
+        # don't do this twice\r
+        self.IsCodeFileCreated = True\r
 \r
-    ## Collect build information for the platform\r
-    #\r
-    #  Collect build information, such as FDF file path, dynamic pcd list,\r
-    #  package list, tool chain configuration, build rules, etc.\r
-    #\r
-    #   @param      Platform            Platform file (DSC file)\r
-    #   @param      Arch                One of arch the platform supports\r
+    ## Create makefile for the platform and mdoules in it\r
     #\r
-    #   @retval     PlatformBuildInfo object\r
+    #   @param      CreateLibraryCodeFile   Flag indicating if the makefile for\r
+    #                                       modules will be created as well\r
     #\r
-    def CollectBuildInfo(self, Platform, Arch):\r
-        Info = PlatformBuildInfo(Platform)\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
-        Info.Arch = Arch\r
-        Info.ToolChain = self.ToolChain\r
-        Info.BuildTarget = self.BuildTarget\r
+        # no need to create makefile for the platform more than once\r
+        if self.IsMakeFileCreated:\r
+            return\r
 \r
-        Info.WorkspaceDir = self.WorkspaceDir\r
-        Info.SourceDir = path.dirname(Platform.DescFilePath)\r
-        Info.OutputDir = Platform.OutputDirectory\r
-        if os.path.isabs(Info.OutputDir):\r
-            Info.BuildDir = path.join(path.abspath(Info.OutputDir), self.BuildTarget + "_" + self.ToolChain)\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
-            Info.BuildDir = path.join(Info.WorkspaceDir, Info.OutputDir, self.BuildTarget + "_" + self.ToolChain)\r
-        Info.MakeFileDir = Info.BuildDir\r
-        if self.Workspace.Fdf != "":\r
-            Info.FdfFile= path.join(self.WorkspaceDir, self.Workspace.Fdf)\r
+            EdkLogger.verbose("Skipped the generation of makefile for platform [%s] [%s]\n" %\r
+                           (self._MetaFile, self.Arch))\r
+        self.IsMakeFileCreated = True\r
 \r
-        Info.NonDynamicPcdList, Info.DynamicPcdList, Info.GuidValue = self.GetPcdList(Platform, Arch)\r
-        Info.PcdTokenNumber = self.GeneratePcdTokenNumber(Platform, Info.NonDynamicPcdList, Info.DynamicPcdList)\r
-        Info.PackageList = self.GetPackageList(Platform, Arch)\r
+    def _GetPlatform(self):\r
+        if self._Platform == None:\r
+            self._Platform = self.BuildDatabase[self._MetaFile, self.Arch]\r
+        return self._Platform\r
 \r
-        self.GetToolDefinition(Info)\r
-        Info.BuildRule = self.GetBuildRule()\r
-        Info.FdTargetList = self.Workspace.FdTargetList\r
-        Info.FvTargetList = self.Workspace.FvTargetList\r
+    def _GetName(self):\r
+        return self.Platform.PlatformName\r
 \r
-        return Info\r
+    def _GetGuid(self):\r
+        return self.Platform.Guid\r
+\r
+    def _GetVersion(self):\r
+        return self.Platform.Version\r
+\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
+    def _GetDebugDir(self):\r
+        return ''\r
+\r
+    def _GetOutputDir(self):\r
+        return self.Platform.OutputDirectory\r
+\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
-        return self.BuildInfo[self.ArchList[0]].MakeFileDir\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, Arch=None):\r
-        if Arch != None:\r
-            Arch = [Arch]\r
-        else:\r
-            Arch = self.ArchList\r
-        Command = tuple()\r
-        for A in Arch:\r
-            if A in self.BuildInfo and "MAKE" in self.BuildInfo[A].ToolPath:\r
-                Command += (self.BuildInfo[A].ToolPath["MAKE"],)\r
-                if "MAKE" in self.BuildInfo[A].ToolOption:\r
-                    NewOption = self.BuildInfo[A].ToolOption["MAKE"].strip()\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
-                      Command += (NewOption,)\r
-                break\r
-        if len(Command) == 0:\r
-            EdkLogger.error("AutoGen", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!")\r
-        return Command\r
-\r
-    ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt\r
-    #\r
-    #   @retval     BuildRule object\r
-    #\r
-    def GetBuildRule(self):\r
-        BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
-        if BuildRuleFile in [None, '']:\r
-            BuildRuleFile = gBuildRuleFile\r
-        return BuildRule(self.Workspace.WorkspaceFile(BuildRuleFile))\r
+                      self._BuildCommand += (NewOption,)\r
+        return self._BuildCommand\r
 \r
     ## Get tool chain definition\r
     #\r
@@ -282,11 +455,17 @@ class PlatformAutoGen:
     #\r
     #   @param      Info    PlatformBuildInfo object to store the definition\r
     #\r
-    def GetToolDefinition(self, Info):\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" % (Info.BuildTarget, Info.ToolChain, Info.Arch, Tool)\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
@@ -325,45 +504,73 @@ class PlatformAutoGen:
 \r
             InputFlag = gIncludeFlag[Family]\r
 \r
-            Info.ToolPath[Tool] = Path\r
-            Info.ToolDllPath[Tool] = Dll\r
-            Info.ToolChainFamily[Tool] = Family\r
-            Info.ToolOption[Tool] = Option\r
-            Info.OutputFlag[Tool] = OutputFlag\r
-            Info.IncludeFlag[Tool] = InputFlag\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
+    def _GetToolPaths(self):\r
+        if self._ToolPath == None:\r
+            self._GetToolDefinition()\r
+        return self._ToolPath\r
+\r
+    def _GetToolDllPaths(self):\r
+        if self._ToolDllPath == None:\r
+            self._GetToolDefinition()\r
+        return self._ToolDllPath\r
+\r
+    def _GetToolStaticLibs(self):\r
+        if self._ToolStaticLib == None:\r
+            self._GetToolDefinition()\r
+        return self._ToolStaticLib\r
+\r
+    def _GetToolChainFamilies(self):\r
+        if self._ToolChainFamily == None:\r
+            self._GetToolDefinition()\r
+        return self._ToolChainFamily\r
+\r
+    def _GetBuildOptions(self):\r
+        if self._BuildOption == None:\r
+            self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)\r
+        return self._BuildOption\r
+\r
+    def _GetOuputFlags(self):\r
+        if self._OutputFlag == None:\r
+            self._GetToolDefinition()\r
+        return self._OutputFlag\r
+\r
+    def _GetIncludeFlags(self):\r
+        if self._IncludeFlag == None:\r
+            self._GetToolDefinition()\r
+        return self._IncludeFlag\r
+\r
+    def _GetToolOptions(self):\r
+        if self._ToolOption == None:\r
+            self._GetToolDefinition()\r
+        return self._ToolOption\r
 \r
-        # get tool options from platform\r
-        BuildOptions = Info.Platform.BuildOptions\r
-        for Key in BuildOptions:\r
-            Family = Key[0]\r
-            Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
-            if Tool not in Info.ToolPath:\r
-                continue\r
-            if Family != None and Family != "" and Family != Info.ToolChainFamily[Tool]:\r
-                continue\r
-            if Target == "*" or Target == Info.BuildTarget:\r
-                if Tag == "*" or Tag == Info.ToolChain:\r
-                    if Arch == "*" or Arch == Info.Arch:\r
-                        Info.BuildOption[Tool] = BuildOptions[Key]\r
-        for Tool in Info.ToolOption:\r
-            if Tool not in Info.BuildOption:\r
-                Info.BuildOption[Tool] = ""\r
-\r
-    def GetPackageList(self, Platform, Arch):\r
-        PackageList = []\r
-        for F in Platform.Modules:\r
-            M = self.ModuleDatabase[Arch][F]\r
-            for P in M.Packages:\r
-                if P in PackageList:\r
-                    continue\r
-                PackageList.append(P)\r
-        for F in Platform.LibraryInstances:\r
-            M = self.ModuleDatabase[Arch][F]\r
-            for P in M.Packages:\r
-                if P in PackageList:\r
-                    continue\r
-                PackageList.append(P)\r
-        return PackageList\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
+    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
@@ -374,24 +581,23 @@ class PlatformAutoGen:
     #\r
     #   @retval     lsit        The list of dynamic PCD\r
     #\r
-    def GetPcdList(self, Platform, Arch):\r
-        NonDynamicPcdList = []\r
-        DynamicPcdList = []\r
+    def _GetPcdList(self):\r
+        self._NonDynamicPcdList = []\r
+        self._DynamicPcdList = []\r
 \r
         # for gathering error information\r
         NotFoundPcdList = set()\r
         NoDatumTypePcdList = set()\r
 \r
-        GuidValue = {}\r
-        for F in Platform.Modules:\r
-            GuidValue.update(F.Guids)\r
-            M = self.ModuleDatabase[Arch][F]\r
-            for Key in M.Pcds:\r
-                PcdFromModule = M.Pcds[Key]\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
+                #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
@@ -401,20 +607,27 @@ class PlatformAutoGen:
                     # for autogen code purpose\r
                     if M.ModuleType in ["PEIM", "PEI_CORE"]:\r
                         PcdFromModule.Phase = "PEI"\r
-                    if PcdFromModule not in DynamicPcdList:\r
-                        DynamicPcdList.append(PcdFromModule)\r
-                elif PcdFromModule not in NonDynamicPcdList:\r
-                    NonDynamicPcdList.append(PcdFromModule)\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(NotFoundPcdList) > 0 or len(NoDatumTypePcdList) > 0:\r
-            NotFoundPcdListString = "\n\t\t".join(NotFoundPcdList)\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) not found in platform:\n\t\t%s"\r
-                                      "\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"\r
-                                      % (NotFoundPcdListString, NoDatumTypePcdListString))\r
-        return NonDynamicPcdList, DynamicPcdList, GuidValue\r
+                            ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"\r
+                                      % NoDatumTypePcdListString)\r
+\r
+    def _GetNonDynamicPcdList(self):\r
+        if self._NonDynamicPcdList == None:\r
+            self._GetPcdList()\r
+        return self._NonDynamicPcdList\r
+\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
     #\r
@@ -423,98 +636,54 @@ class PlatformAutoGen:
     #\r
     #   @retval     dict            A dict object containing the PCD and its token number\r
     #\r
-    def GeneratePcdTokenNumber(self, Platform, NonDynamicPcdList, DynamicPcdList):\r
-        PcdTokenNumber = sdict()\r
-        TokenNumber = 1\r
-        for Pcd in DynamicPcdList:\r
-            if Pcd.Phase == "PEI":\r
-                EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
-                PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\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
-\r
-        for Pcd in DynamicPcdList:\r
-            if Pcd.Phase == "DXE":\r
-                EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
-                PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
-                TokenNumber += 1\r
-\r
-        for Pcd in NonDynamicPcdList:\r
-            PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
-            TokenNumber += 1\r
-        return PcdTokenNumber\r
-\r
-    ## Create autogen object for each module in platform\r
-    #\r
-    def CreateModuleAutoGen(self):\r
-        for Arch in self.BuildInfo:\r
-            Info = self.BuildInfo[Arch]\r
-            for ModuleFile in Info.Platform.LibraryInstances:\r
-                ModuleAutoGen.New(self.Workspace, Info.Platform, ModuleFile,\r
-                                         Info.BuildTarget, Info.ToolChain, Info.Arch)\r
-\r
-            for ModuleFile in Info.Platform.Modules:\r
-                ModuleAutoGen.New(self.Workspace, Info.Platform, ModuleFile,\r
-                                         Info.BuildTarget, Info.ToolChain, Info.Arch)\r
-\r
-    ## Create makefile for the platform and mdoules in it\r
-    #\r
-    #   @param      CreateLibraryCodeFile   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 Arch in self.BuildInfo:\r
-                Info = self.BuildInfo[Arch]\r
-                for ModuleFile in Info.Platform.LibraryInstances:\r
-                    AutoGenObject = ModuleAutoGen.New(self.Workspace, Info.Platform, ModuleFile,\r
-                                                      Info.BuildTarget, Info.ToolChain, Info.Arch)\r
-                    AutoGenObject.CreateMakeFile(False)\r
-\r
-                for ModuleFile in Info.Platform.Modules:\r
-                    AutoGenObject = ModuleAutoGen.New(self.Workspace, Info.Platform, ModuleFile,\r
-                                                      Info.BuildTarget, Info.ToolChain, Info.Arch)\r
-                    AutoGenObject.CreateMakeFile(False)\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.Makefile(self.BuildInfo)\r
-        if Makefile.Generate():\r
-            EdkLogger.verbose("Generated makefile for platform [%s] [%s]\n" %\r
-                           (self.PlatformFile, " ".join(self.ArchList)))\r
-        else:\r
-            EdkLogger.verbose("Skipped the generation of makefile for platform [%s] [%s]\n" %\r
-                           (self.PlatformFile, " ".join(self.ArchList)))\r
-        self.IsMakeFileCreated = 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 Arch in self.BuildInfo:\r
-            Info = self.BuildInfo[Arch]\r
-            for ModuleFile in Info.Platform.LibraryInstances:\r
-                AutoGenObject = ModuleAutoGen.New(self.Workspace, Info.Platform, ModuleFile,\r
-                                                  Info.BuildTarget, Info.ToolChain, Info.Arch)\r
-                AutoGenObject.CreateCodeFile()\r
-\r
-            for ModuleFile in Info.Platform.Modules:\r
-                AutoGenObject = ModuleAutoGen.New(self.Workspace, Info.Platform, ModuleFile,\r
-                                                  Info.BuildTarget, Info.ToolChain, Info.Arch)\r
-                AutoGenObject.CreateCodeFile()\r
-        # don't do this twice\r
-        self.IsCodeFileCreated = True\r
+        return self._PcdTokenNumber\r
+\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
+    def _GetModuleAutoGenList(self):\r
+        if self._ModuleAutoGenList == None:\r
+            self._GetAutoGenObjectList()\r
+        return self._ModuleAutoGenList\r
+\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
@@ -524,101 +693,349 @@ class PlatformAutoGen:
     #   @param      Module  The module file\r
     #   @param      Arch    The arch the module will be built for\r
     #\r
-    def IsValidModule(self, Module, Arch):\r
-        if Arch not in self.Workspace.SupArchList:\r
-            return False\r
-            #EdkLogger.error("AutoGen", AUTOGEN_ERROR, "[%s] is not supported by active platform [%s] [%s]!"\r
-            #                                          % (Arch, self.PlatformFile, self.Workspace.SupArchList))\r
-        if Arch not in self.ArchList:\r
-            return False\r
-            #EdkLogger.error("AutoGen", AUTOGEN_ERROR, "[%s] is not supported by current build configuration!" % Arch)\r
+    def ValidModule(self, Module):\r
+        #if Arch not in self.Workspace.SupArchList:\r
+        #    return False\r
+        #    #EdkLogger.error("AutoGen", AUTOGEN_ERROR, "[%s] is not supported by active platform [%s] [%s]!"\r
+        #    #                                          % (Arch, self._MetaFile, self.Workspace.SupArchList))\r
+        #if Arch not in self.ArchList:\r
+        #    return False\r
+        #    #EdkLogger.error("AutoGen", AUTOGEN_ERROR, "[%s] is not supported by current build configuration!" % Arch)\r
+        return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances\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 Arch not in self.ModuleDatabase or str(Module) not in self.ModuleDatabase[Arch]:\r
-            for A in self.ModuleDatabase:\r
-                if str(Module) in self.ModuleDatabase[A]:\r
-                    break\r
-            else:\r
-                EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Module is not in active platform!",\r
-                                ExtraData=Module)\r
-            return False\r
-        return True\r
+                if LibraryModule == None:\r
+                    continue\r
 \r
-    ## Find the package containing the module\r
-    #\r
-    # Find out the package which contains the given module, according to the path\r
-    # of the module and the package.\r
-    #\r
-    # @param  Module            The module to be found for\r
-    #\r
-    # @retval package           Package object if found\r
-    # @retval None              None if not found\r
-    #\r
-    def GetModuleOwnerPackage(self, Module):\r
-        for Arch in self.PackageDatabase:\r
-            Pdb = self.PackageDatabase[Arch]\r
-            for PackagePath in Pdb:\r
-                PackageDir = path.dirname(PackagePath)\r
-                #\r
-                # if package's path is the first part of module's path, bingo!\r
-                #\r
-                if str(Module).find(PackageDir) == 0:\r
-                    return Pdb[PackagePath]\r
-        # nothing found\r
-        return None\r
+                if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:\r
+                    Constructor.append(LibraryModule)\r
 \r
-    ## Get platform object\r
-    #\r
-    #   @param      PlatformFile    The file path of the platform\r
-    #   @param      Arch            One of the arch the platform supports\r
-    #\r
-    #   @retval     object          The object of the platform\r
-    #\r
-    def GetPlatformObject(self, PlatformFile, Arch):\r
-        if Arch not in self.PlatformDatabase or PlatformFile not in self.PlatformDatabase[Arch]:\r
-            return None\r
-        return self.PlatformDatabase[Arch][PlatformFile]\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
-    ## Get package object\r
-    #\r
-    #   @param      PackageFile     The file path of the package\r
-    #   @param      Arch            One of the arch the package supports\r
-    #\r
-    #   @retval     object          The object of the package\r
-    #\r
-    def GetPackageObject(self, PackageFile, Arch):\r
-        if Arch not in self.PackageDatabase or PackageFile not in self.PackageDatabase[Arch]:\r
-            return None\r
-        return self.PackageDatabase[Arch][PackageFile]\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
-    ## Get module object\r
-    #\r
-    #   @param      ModuleFile      The file path of the module\r
-    #   @param      Arch            One of the arch the module supports\r
-    #\r
-    #   @retval     object          The object of the module\r
-    #\r
-    def GetModuleObject(self, ModuleFile, Arch):\r
-        if Arch not in self.ModuleDatabase or ModuleFile not in self.ModuleDatabase[Arch]:\r
-            return None\r
-        return self.ModuleDatabase[Arch][ModuleFile]\r
+            # remove node from Q\r
+            Node = Q.pop()\r
+            # output Node\r
+            SortedLibraryList.append(Node)\r
 \r
-    ## Add ModuleAutoGen object for a module in platform build information\r
-    #\r
-    #   @param      ModuleAutoGen   The ModuleAutoGen object for a module\r
-    #   @param      Arch            The arch of the module\r
-    #\r
-    def AddModuleAutoGen(self, ModuleAutoGen, Arch):\r
-        if ModuleAutoGen not in self.BuildInfo[Arch].ModuleAutoGenList:\r
-            self.BuildInfo[Arch].ModuleAutoGenList.append(ModuleAutoGen)\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
-    ## Add ModuleAutoGen object for a library in platform build information\r
-    #\r
-    #   @param      LibraryAutoGen  The ModuleAutoGen object for a library module\r
-    #   @param      Arch            The arch of the library\r
-    #\r
-    def AddLibraryAutoGen(self, LibraryAutoGen, Arch):\r
-        if LibraryAutoGen not in self.BuildInfo[Arch].LibraryAutoGenList:\r
-            self.BuildInfo[Arch].LibraryAutoGenList.append(LibraryAutoGen)\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
+    def _OverridePcd(self, ToPcd, FromPcd):\r
+        # \r
+        # in case there's PCDs coming from FDF file, which have no type given.\r
+        # at this point, PcdInModule.Type has the type found from dependent\r
+        # package\r
+        # \r
+        if FromPcd != None:\r
+            if FromPcd.Type not in [None, '']:\r
+                ToPcd.Type = FromPcd.Type\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
+    def ApplyPcdSetting(self, Module):\r
+        for Name,Guid in Module.Pcds:\r
+            PcdInModule = Module.Pcds[Name,Guid]\r
+            if (Name,Guid) in self.Platform.Pcds:\r
+                PcdInPlatform = self.Platform.Pcds[Name,Guid]\r
+            else:\r
+                PcdInPlatform = None\r
+            self._OverridePcd(PcdInModule, PcdInPlatform)\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])\r
+        return Module.Pcds.values()\r
+\r
+    ##\r
+    # for R8.x 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
+    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
+    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
 ## AutoGen class\r
 #\r
@@ -627,12 +1044,7 @@ class PlatformAutoGen:
 # to the [depex] section in module's inf file. The result of parsing unicode file\r
 # has been incorporated either.\r
 #\r
-class ModuleAutoGen(object):\r
-    # The cache for the objects of ModuleAutoGen\r
-    _Database = {}\r
-    # The cache for the object of PlatformAutoGen\r
-    _PlatformAutoGen = None\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
@@ -646,13 +1058,22 @@ class ModuleAutoGen(object):
     #   @param      Toolchain           Name of tool chain\r
     #   @param      Arch                The arch the module supports\r
     #\r
-    def _Init(self, Workspace, PlatformAutoGenObj, ModuleFile, Target, Toolchain, Arch):\r
-        self.ModuleFile = str(ModuleFile)\r
-        self.PlatformFile = PlatformAutoGenObj.PlatformFile\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
+        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
@@ -661,186 +1082,132 @@ class ModuleAutoGen(object):
         self.IsMakeFileCreated = False\r
         self.IsCodeFileCreated = False\r
 \r
-        self.PlatformAutoGen = PlatformAutoGenObj\r
-        if not self.PlatformAutoGen.IsValidModule(ModuleFile, self.Arch):\r
-            return False\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
-        #\r
-        # autogen for module\r
-        #\r
-        EdkLogger.verbose("\nAutoGen module [%s] [%s]" % (ModuleFile, self.Arch))\r
-\r
-        self.Platform = self.PlatformAutoGen.GetPlatformObject(self.PlatformFile, self.Arch)\r
-        self.Module = self.PlatformAutoGen.GetModuleObject(self.ModuleFile, self.Arch)\r
-\r
-        self.Package = self.PlatformAutoGen.GetModuleOwnerPackage(self.Module)\r
-\r
-        self.AutoGenC = TemplateString()\r
-        self.AutoGenH = TemplateString()\r
-\r
-        self.BuildInfo = self.GetModuleBuildInfo()\r
         return True\r
 \r
-    ## "==" operator\r
-    #\r
-    #  Use module file path and arch to do the comparison\r
-    #\r
-    #   @retval True    if the file path and arch are equal\r
-    #   @retval False   if the file path or arch are different\r
-    #\r
-    def __eq__(self, Other):\r
-        return Other != None and self.ModuleFile == Other.ModuleFile and self.Arch == Other.Arch\r
 \r
-    ## hash() operator\r
-    #\r
-    #  The file path and arch of the module will be used to represent hash value of this object\r
-    #\r
-    #   @retval int     Hash value of the file path and arch name of the module\r
-    #\r
-    def __hash__(self):\r
-        return hash(self.ModuleFile) + hash(self.Arch)\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
-    ## String representation of this object\r
-    #\r
-    #   @retval     string  The string of file path and arch\r
-    #\r
-    def __str__(self):\r
-        return "%s [%s]" % (self.ModuleFile, self.Arch)\r
+    def _GetBaseName(self):\r
+        return self.Module.BaseName\r
 \r
-    ## Factory method to create a ModuleAutoGen object\r
-    #\r
-    #   This method will check if an object of ModuleAutoGen has been created\r
-    #   for given platform. And if true, just return it. Otherwise it will create\r
-    #   a new ModuleAutoGen. That means there will be only one ModuleAutoGen\r
-    #   object for the same platform.\r
-    #\r
-    #   @param      Workspace           EdkIIWorkspaceBuild object\r
-    #   @param      Platform            Platform file (DSC file)\r
-    #   @param      Module              Module file (INF file)\r
-    #   @param      Target              Build target (DEBUG, RELEASE)\r
-    #   @param      Toolchain           Name of tool chain\r
-    #   @param      Arch                The arch of the module\r
-    #\r
-    #   @retval     ModuleAutoGen object\r
-    #\r
-    @staticmethod\r
-    def New(Workspace, Platform, Module, Target, Toolchain, Arch):\r
-        # creating module autogen needs platform's autogen\r
-        _PlatformAutoGen = PlatformAutoGen.New(Workspace, Platform, Target, Toolchain, None)\r
-        if _PlatformAutoGen == None:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No platform AutoGen available!")\r
+    def _GetGuid(self):\r
+        return self.Module.Guid\r
 \r
-        # check if the autogen for the module has been created or not\r
-        Key = (Module, Target, Toolchain, Arch)\r
-        if Key not in ModuleAutoGen._Database:\r
-            if Arch == None or Arch == "":\r
-                return None\r
-            AutoGenObject = ModuleAutoGen()\r
-            if AutoGenObject._Init(Workspace, _PlatformAutoGen, Module, Target, Toolchain, Arch) == False:\r
-                return None\r
-            ModuleAutoGen._Database[Key] = AutoGenObject\r
+    def _GetVersion(self):\r
+        return self.Module.Version\r
 \r
-            # for new ModuleAutoGen object, put it in platform's AutoGen\r
-            if AutoGenObject.BuildInfo.IsLibrary:\r
-                _PlatformAutoGen.AddLibraryAutoGen(AutoGenObject, Arch)\r
-            else:\r
-                _PlatformAutoGen.AddModuleAutoGen(AutoGenObject, Arch)\r
-            return AutoGenObject\r
-\r
-        return ModuleAutoGen._Database[Key]\r
-\r
-    ## Gather module build information\r
-    #\r
-    #   @retval     Info    The object of ModuleBuildInfo\r
-    #\r
-    def GetModuleBuildInfo(self):\r
-        Info = ModuleBuildInfo(self.Module)\r
-        self.BuildInfo = Info\r
-        Info.PlatformInfo = self.PlatformAutoGen.BuildInfo[self.Arch]\r
-\r
-        # basic information\r
-        Info.WorkspaceDir = self.WorkspaceDir\r
-        Info.BuildTarget = self.BuildTarget\r
-        Info.ToolChain = self.ToolChain\r
-        Info.Arch = self.Arch\r
-        # Info.IsBinary = self.Module.BinaryModule\r
-        Info.BaseName = self.Module.BaseName\r
-        Info.FileBase, Info.FileExt = path.splitext(path.basename(self.Module.DescFilePath))\r
-        Info.SourceDir = path.dirname(self.Module.DescFilePath)\r
-        Info.BuildDir = os.path.join(Info.PlatformInfo.BuildDir,\r
-                                     Info.Arch,\r
-                                     Info.SourceDir,\r
-                                     Info.FileBase)\r
-        Info.OutputDir = os.path.join(Info.BuildDir, "OUTPUT")\r
-        Info.DebugDir = os.path.join(Info.BuildDir, "DEBUG")\r
-        Info.MakeFileDir = Info.BuildDir\r
-        if not os.path.isabs(Info.BuildDir):\r
-            os.chdir(Info.PlatformInfo.BuildDir)\r
-        CreateDirectory(Info.OutputDir)\r
-        CreateDirectory(Info.DebugDir)\r
-        os.chdir(self.WorkspaceDir)\r
+    def _GetModuleType(self):\r
+        return self.Module.ModuleType\r
 \r
-        for Type in self.Module.CustomMakefile:\r
-            MakeType = gMakeTypeMap[Type]\r
-            Info.CustomMakefile[MakeType] = os.path.join(Info.SourceDir, self.Module.CustomMakefile[Type])\r
+    def _GetComponentType(self):\r
+        return self.Module.ComponentType\r
 \r
-        if self.Module.LibraryClass != None and self.Module.LibraryClass != []:\r
-            Info.IsLibrary = True\r
-            Info.DependentLibraryList = []\r
-        else:\r
-            Info.IsLibrary = False\r
-            Info.DependentLibraryList = self.GetSortedLibraryList()\r
-\r
-        Info.DependentPackageList = self.GetDependentPackageList()\r
-        Info.DerivedPackageList = self.GetDerivedPackageList()\r
-\r
-        Info.BuildOption = self.GetModuleBuildOption(Info.PlatformInfo)\r
-        if "DLINK" in Info.PlatformInfo.ToolStaticLib:\r
-            Info.SystemLibraryList = Info.PlatformInfo.ToolStaticLib["DLINK"]\r
-\r
-        Info.PcdIsDriver = self.Module.PcdIsDriver\r
-        Info.PcdList = self.GetPcdList(Info.DependentLibraryList)\r
-        Info.GuidList = self.Module.Guids\r
-        Info.ProtocolList = self.Module.Protocols\r
-        Info.PpiList = self.Module.Ppis\r
-        Info.Macro = self.GetMacroList()\r
-        Info.DepexList = self.GetDepexTokenList(Info)\r
-\r
-        if Info.AutoGenVersion < 0x00010005:\r
-            # r8 module needs to put DEBUG_DIR at the end search path and not to use SOURCE_DIR all the time\r
-            Info.IncludePathList = self.GetIncludePathList(Info.DependentPackageList)\r
-            Info.IncludePathList.append(Info.DebugDir)\r
-        else:\r
-            Info.IncludePathList = [os.path.join(Info.WorkspaceDir, Info.SourceDir), Info.DebugDir]\r
-            Info.IncludePathList.extend(self.GetIncludePathList(Info.DependentPackageList))\r
+    def _GetPcdIsDriver(self):\r
+        return self.Module.PcdIsDriver\r
 \r
-        Info.SourceFileList = self.GetSourceFileList(Info)\r
-        Info.AutoGenFileList = self.GetAutoGenFileList(Info)\r
-        Info.BinaryFileDict = self.GetBinaryFiles()\r
+    def _GetAutoGenVersion(self):\r
+        return self.Module.AutoGenVersion\r
 \r
-        return Info\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
+    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
+    def _GetOutputDir(self):\r
+        if self._OutputDir == None:\r
+            self._OutputDir = path.join(self.BuildDir, "OUTPUT")\r
+        return self._OutputDir\r
+\r
+    def _GetDebugDir(self):\r
+        if self._DebugDir == None:\r
+            self._DebugDir = path.join(self.BuildDir, "DEBUG")\r
+        return self._DebugDir\r
+\r
+    def _GetMakeFileDir(self):\r
+        return path.join(PlatformInfo.BuildDir, self.BuildDir)\r
+\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.BuildInfo.MakeFileDir\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.PlatformAutoGen.GetBuildCommand(self.Arch)\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
+    def _GetDerivedPackageList(self):\r
         PackageList = []\r
-        for M in [self.Module] + self.BuildInfo.DependentLibraryList:\r
+        for M in [self.Module] + self.DependentLibraryList:\r
             for Package in M.Packages:\r
                 if Package in PackageList:\r
                     continue\r
@@ -852,58 +1219,34 @@ class ModuleAutoGen(object):
     #   @param      Info    The object of ModuleBuildInfo\r
     #   @retval     list    The token list of the dependency expression after parsed\r
     #\r
-    def GetDepexTokenList(self, Info):\r
-        Dxs = self.Module.Depex\r
-        EdkLogger.verbose("DEPEX string = %s" % Dxs)\r
-        #\r
-        # Append depex from dependent libraries\r
-        #\r
-        for Lib in Info.DependentLibraryList:\r
-            if Lib.Depex != None and Lib.Depex != "":\r
-                if Dxs == None or Dxs == "":\r
-                    Dxs = Lib.Depex\r
-                else:\r
-                    Dxs += " AND (" + Lib.Depex + ")"\r
-                EdkLogger.verbose("DEPEX string (+%s) = %s" % (Lib.BaseName, Dxs))\r
-        if Dxs == "":\r
-            return []\r
-\r
-        TokenList = gDepexTokenPattern.findall(Dxs)\r
-        EdkLogger.debug(EdkLogger.DEBUG_8, "TokenList(raw) = %s" % (TokenList))\r
-        for I in range(0, len(TokenList)):\r
-            Token = TokenList[I].strip()\r
-            if Token.endswith(".inf"):  # module file name\r
-                ModuleFile = os.path.normpath(Token)\r
-                Token = gModuleDatabase[ModuleFile].Guid\r
-            elif Token not in ['(', ')']+GenDepex.DependencyExpression.SupportedOpcode+\\r
-                 GenDepex.DependencyExpression.SupportedOperand:   # GUID C Name\r
-                GuidCName = Token\r
-                for P in Info.DerivedPackageList:\r
-                    if GuidCName in P.Protocols:\r
-                        Token = P.Protocols[GuidCName]\r
-                        break\r
-                    elif GuidCName in P.Ppis:\r
-                        Token = P.Ppis[GuidCName]\r
-                        break\r
-                    elif GuidCName in P.Guids:\r
-                        Token = P.Guids[GuidCName]\r
-                        break\r
-                else:\r
-                    PackageListString = "\n\t".join([str(P) for P in self.BuildInfo.DerivedPackageList])\r
-                    EdkLogger.error("AutoGen", AUTOGEN_ERROR,\r
-                                    "GUID [%s] used in module [%s] cannot be found in dependent packages!"\r
-                                    % (GuidCName, self.Module),\r
-                                    ExtraData=PackageListString)\r
-            TokenList[I] = Token\r
-        EdkLogger.debug(EdkLogger.DEBUG_8, "TokenList(guid) = %s" % " ".join(TokenList))\r
-        return TokenList\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 ["%s %s" % (Name, self.Module.Specification[Name]) for Name in self.Module.Specification]\r
+    def _GetMacroList(self):\r
         return self.Module.Specification\r
 \r
     ## Tool option for the module build\r
@@ -911,50 +1254,28 @@ class ModuleAutoGen(object):
     #   @param      PlatformInfo    The object of PlatformBuildInfo\r
     #   @retval     dict            The dict containing valid options\r
     #\r
-    def GetModuleBuildOption(self, PlatformInfo):\r
-        BuildOption = self.Module.BuildOptions\r
-        OptionList = {}\r
-        for Key in BuildOption:\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 PlatformInfo.ToolPath:\r
-                continue\r
-            # if tool chain family doesn't match, skip it\r
-            if Family != None and Family != "" and Family != PlatformInfo.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 OptionList:\r
-                            OptionList[Tool] = BuildOption[Key]\r
-                        else:\r
-                            # append options for the same tool\r
-                            OptionList[Tool] = OptionList[Tool] + " " + BuildOption[Key]\r
-        # for those tools that have no option in module file, give it a empty string\r
-        for Tool in PlatformInfo.ToolOption:\r
-            if Tool not in OptionList:\r
-                OptionList[Tool] = ""\r
-\r
-        return OptionList\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
-    #   @param      PlatformInfo    The object of PlatformBuildInfo\r
-    #   @retval     list            The list of files which can be built later\r
-    #\r
-    def GetSourceFileList(self, Info):\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 Info.PlatformInfo.ToolChainFamily:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [CC] is not supported for %s [%s, %s]" \\r
-                             % (Info.ToolChain, Info.BuildTarget, Info.Arch))\r
-        ToolChainFamily = Info.PlatformInfo.ToolChainFamily["CC"]\r
-        BuildRule = Info.PlatformInfo.BuildRule\r
-        FileList = []\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
@@ -971,9 +1292,9 @@ class ModuleAutoGen(object):
             # 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.BuildInfo.SourceDir, Dir)\r
-                if Dir not in self.BuildInfo.IncludePathList:\r
-                    self.BuildInfo.IncludePathList.insert(0, 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
@@ -982,19 +1303,24 @@ class ModuleAutoGen(object):
             FileType, RuleObject = BuildRule.Get(Ext, ToolChainFamily)\r
             # unicode must be processed by AutoGen\r
             if FileType == "Unicode-Text-File":\r
-                self.BuildInfo.UnicodeFileList.append(os.path.join(self.WorkspaceDir, self.BuildInfo.SourceDir, SourceFile))\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
-                Info.DepexList = []\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 FileList:\r
-                FileList.append([SourceFile, FileType, RuleObject])\r
+            if [SourceFile, FileType, RuleObject] not in self._SourceFileList:\r
+                self._SourceFileList.append([SourceFile, FileType, RuleObject])\r
 \r
-        return FileList\r
+        return self._SourceFileList\r
+\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
@@ -1003,163 +1329,139 @@ class ModuleAutoGen(object):
     #   @param      PlatformInfo    The object of PlatformBuildInfo\r
     #   @retval     list            The list of files which can be built later\r
     #\r
-    def GetBinaryFiles(self):\r
-        FileDict = {}\r
-        for F in self.Module.Binaries:\r
-            if F.Target != '*' and F.Target != self.BuildTarget:\r
-                continue\r
-            if F.FileType not in FileDict:\r
-                FileDict[F.FileType] = []\r
-            FileDict[F.FileType].append(F.BinaryFile)\r
-        return FileDict\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
-        PackageList = []\r
-        for Package in self.Module.Packages:\r
-            if Package in PackageList:\r
-                continue\r
-            PackageList.append(Package)\r
-        return PackageList\r
+    def _GetDependentPackageList(self):\r
+        return self.Module.Packages\r
 \r
     ## Return the list of auto-generated code file\r
     #\r
     #   @param      BuildInfo   The object ModuleBuildInfo\r
     #   @retval     list        The list of auto-generated file\r
     #\r
-    def GetAutoGenFileList(self, BuildInfo):\r
-        GenC.CreateCode(BuildInfo, self.AutoGenC, self.AutoGenH)\r
-        FileList = []\r
-        if self.AutoGenC.String != "":\r
-            FileList.append("AutoGen.c")\r
-        if self.AutoGenH.String != "":\r
-            FileList.append("AutoGen.h")\r
-        return FileList\r
-\r
-    ## Get the list of library module object\r
-    #\r
-    #   @retval     list    The list of library module list\r
-    #\r
-    def GetSortedLibraryList(self):\r
-        LibraryList = []\r
-        for Key in self.Module.LibraryClasses:\r
-            Library = self.Module.LibraryClasses[Key]\r
-            if Library not in LibraryList:\r
-                LibraryList.append(Library)\r
-        return LibraryList\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
+    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
     #   @param      DependentLibraryList    The list of dependent library\r
     #   @retval     list                    The list of PCD\r
     #\r
-    def GetPcdList(self, DependentLibraryList):\r
-        PcdList = []\r
-        for PcdKey in self.Module.Pcds:\r
-            PcdList.append(self.Module.Pcds[PcdKey])\r
-        return PcdList\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] = 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
-        Guid = {}\r
-        Key = ""\r
-        for Key in self.Module.Guids:\r
-            for P in self.BuildInfo.DerivedPackageList:\r
-                if Key in P.Guids:\r
-                    Guid[Key] = P.Guids[Key]\r
-                    break\r
-                if Key in P.Protocols:\r
-                    Guid[Key] = P.Protocols[Key]\r
-                    break\r
-                if Key in P.Ppis:\r
-                    Guid[Key] = P.Ppis[Key]\r
-                    break\r
-            else:\r
-                PackageListString = "\t" + "\n\t".join([str(P) for P in self.BuildInfo.DerivedPackageList])\r
-                EdkLogger.error("AutoGen", AUTOGEN_ERROR, 'GUID [%s] used by [%s] cannot be found in dependent packages' % (Key, self.Module),\r
-                                ExtraData=PackageListString)\r
-        return Guid\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 GetProtocolGuidList(self):\r
-        Guid = {}\r
-        Key = ""\r
-        for Key in self.Module.Protocols:\r
-            for P in self.BuildInfo.DerivedPackageList:\r
-                if Key in P.Guids:\r
-                    Guid[Key] = P.Guids[Key]\r
-                    break\r
-                if Key in P.Protocols:\r
-                    Guid[Key] = P.Protocols[Key]\r
-                    break\r
-                if Key in P.Ppis:\r
-                    Guid[Key] = P.Ppis[Key]\r
-                    break\r
-            else:\r
-                PackageListString = "\t" + "\n\t".join([str(P) for P in self.BuildInfo.DerivedPackageList])\r
-                EdkLogger.error("AutoGen", AUTOGEN_ERROR, 'Protocol [%s] used by [%s] cannot be found in dependent packages' % (Key, self.Module),\r
-                                ExtraData=PackageListString)\r
-        return Guid\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 GetPpiGuidList(self):\r
-        Guid = {}\r
-        Key = ""\r
-        for Key in self.Module.Ppis:\r
-            for P in self.BuildInfo.DerivedPackageList:\r
-                if Key in P.Guids:\r
-                    Guid[Key] = P.Guids[Key]\r
-                    break\r
-                if Key in P.Protocols:\r
-                    Guid[Key] = P.Protocols[Key]\r
-                    break\r
-                if Key in P.Ppis:\r
-                    Guid[Key] = P.Ppis[Key]\r
-                    break\r
-            else:\r
-                PackageListString = "\t" + "\n\t".join([str(P) for P in self.BuildInfo.DerivedPackageList])\r
-                EdkLogger.error("AutoGen", AUTOGEN_ERROR, 'PPI [%s] used by [%s] cannot be found in dependent packages' % (Key, self.Module),\r
-                                ExtraData=PackageListString)\r
-        return Guid\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
     #   @param      DependentPackageList    The list of package object\r
     #   @retval     list                    The list path\r
     #\r
-    def GetIncludePathList(self, DependentPackageList):\r
-        IncludePathList = []\r
-        if self.BuildInfo.AutoGenVersion < 0x00010005:\r
-            for Inc in self.Module.Includes:\r
-                # '.' means "relative to module directory".\r
-                if Inc[0] == ".":\r
-                    Inc = os.path.join(self.WorkspaceDir, self.BuildInfo.SourceDir, Inc)\r
-                else:\r
-                    Inc = os.path.join(self.WorkspaceDir, Inc)\r
-                IncludePathList.append(Inc)\r
-                # for r8 modules\r
-                IncludePathList.append(os.path.join(Inc, self.Arch.capitalize()))\r
-\r
-        for Package in DependentPackageList:\r
-            PackageDir = os.path.join(self.WorkspaceDir, path.dirname(Package.DescFilePath))\r
-            IncludePathList.append(PackageDir)\r
-            for Inc in Package.Includes:\r
-                Inc = os.path.join(PackageDir, Inc)\r
-                if Inc not in IncludePathList:\r
-                    IncludePathList.append(Inc)\r
-        return IncludePathList\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
@@ -1170,23 +1472,21 @@ class ModuleAutoGen(object):
         if self.IsMakeFileCreated:\r
             return\r
 \r
-        PlatformInfo = self.BuildInfo.PlatformInfo\r
-        if CreateLibraryMakeFile:\r
-            for Lib in self.BuildInfo.DependentLibraryList:\r
-                EdkLogger.debug(EdkLogger.DEBUG_1, "###" + str(Lib))\r
-                LibraryAutoGen = ModuleAutoGen.New(self.Workspace, self.Platform, Lib,\r
-                                                   self.BuildTarget, self.ToolChain, self.Arch)\r
-                if LibraryAutoGen not in self.BuildInfo.LibraryAutoGenList:\r
-                    self.BuildInfo.LibraryAutoGenList.append(LibraryAutoGen)\r
+        PlatformInfo = self.PlatformInfo\r
+        if not self.IsLibrary and CreateLibraryMakeFile:\r
+            for LibraryAutoGen in self.LibraryAutoGenList:\r
                 LibraryAutoGen.CreateMakeFile()\r
 \r
-        Makefile = GenMake.Makefile(self.BuildInfo)\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.BuildInfo.Name, self.BuildInfo.Arch))\r
+                           (self.Name, self.Arch))\r
         else:\r
             EdkLogger.verbose("Skipped the generation of makefile for module %s [%s]" %\r
-                              (self.BuildInfo.Name, self.BuildInfo.Arch))\r
+                              (self.Name, self.Arch))\r
 \r
         self.IsMakeFileCreated = True\r
 \r
@@ -1199,145 +1499,103 @@ class ModuleAutoGen(object):
         if self.IsCodeFileCreated:\r
             return\r
 \r
-        PlatformInfo = self.BuildInfo.PlatformInfo\r
-        if CreateLibraryCodeFile:\r
-            for Lib in self.BuildInfo.DependentLibraryList:\r
-                LibraryAutoGen = ModuleAutoGen.New(self.Workspace, self.Platform, Lib,\r
-                                                          self.BuildTarget, self.ToolChain, self.Arch)\r
-                if LibraryAutoGen not in self.BuildInfo.LibraryAutoGenList:\r
-                    self.BuildInfo.LibraryAutoGenList.append(LibraryAutoGen)\r
+        PlatformInfo = self.PlatformInfo\r
+        if not self.IsLibrary and CreateLibraryCodeFile:\r
+            for LibraryAutoGen in self.LibraryAutoGenList:\r
                 LibraryAutoGen.CreateCodeFile()\r
 \r
-        os.chdir(self.BuildInfo.DebugDir)\r
         AutoGenList = []\r
         IgoredAutoGenList = []\r
-        if self.AutoGenC.String != "":\r
-            if GenC.Generate(gAutoGenCodeFileName, self.AutoGenC.String):\r
-                AutoGenList.append(gAutoGenCodeFileName)\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(gAutoGenCodeFileName)\r
+                IgoredAutoGenList.append(File)\r
 \r
-        if self.AutoGenH.String != "":\r
-            if GenC.Generate(gAutoGenHeaderFileName, self.AutoGenH.String):\r
-                AutoGenList.append(gAutoGenHeaderFileName)\r
-            else:\r
-                IgoredAutoGenList.append(gAutoGenHeaderFileName)\r
+        if self.DepexList != []:\r
+            Dpx = GenDepex.DependencyExpression(self.DepexList, self.ModuleType, True)\r
+            DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}\r
 \r
-        os.chdir(self.BuildInfo.OutputDir)\r
-        if self.BuildInfo.DepexList != []:\r
-            Dpx = GenDepex.DependencyExpression(self.BuildInfo.DepexList, self.BuildInfo.ModuleType, True)\r
-            DpxFile = gAutoGenDepexFileName % {"module_name" : self.BuildInfo.Name}\r
-            if Dpx.Generate(DpxFile):\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.BuildInfo.Name, self.BuildInfo.Arch))\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.BuildInfo.Name, self.BuildInfo.Arch))\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.BuildInfo.Name, self.BuildInfo.Arch))\r
+                           (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))\r
 \r
         self.IsCodeFileCreated = True\r
-        os.chdir(self.WorkspaceDir)\r
         return AutoGenList\r
 \r
-# Version and Copyright\r
-__version_number__ = "0.01"\r
-__version__ = "%prog Version " + __version_number__\r
-__copyright__ = "Copyright (c) 2007, Intel Corporation. All rights reserved."\r
-\r
-## Parse command line options\r
-#\r
-# Using standard Python module optparse to parse command line option of this tool.\r
-#\r
-# @retval Options   A optparse.Values object containing the parsed options\r
-# @retval InputFile Path of file to be trimmed\r
-#\r
-def GetOptions():\r
-    OptionList = [\r
-        make_option("-a", "--arch", dest="Arch",\r
-                          help="The input file is preprocessed source code, including C or assembly code"),\r
-        make_option("-p", "--platform", dest="ActivePlatform",\r
-                          help="The input file is preprocessed VFR file"),\r
-        make_option("-m", "--module", dest="ActiveModule",\r
-                          help="Convert standard hex format (0xabcd) to MASM format (abcdh)"),\r
-        make_option("-f", "--FDF-file", dest="FdfFile",\r
-                          help="Convert standard hex format (0xabcd) to MASM format (abcdh)"),\r
-        make_option("-o", "--output", dest="OutputDirectory",\r
-                          help="File to store the trimmed content"),\r
-        make_option("-t", "--toolchain-tag", dest="ToolChain",\r
-                          help=""),\r
-        make_option("-k", "--msft", dest="MakefileType", action="store_const", const="nmake",\r
-                          help=""),\r
-        make_option("-g", "--gcc", dest="MakefileType", action="store_const", const="gmake",\r
-                          help=""),\r
-        make_option("-v", "--verbose", dest="LogLevel", action="store_const", const=EdkLogger.VERBOSE,\r
-                          help="Run verbosely"),\r
-        make_option("-d", "--debug", dest="LogLevel", type="int",\r
-                          help="Run with debug information"),\r
-        make_option("-q", "--quiet", dest="LogLevel", action="store_const", const=EdkLogger.QUIET,\r
-                          help="Run quietly"),\r
-        make_option("-?", action="help", help="show this help message and exit"),\r
-    ]\r
-\r
-    # use clearer usage to override default usage message\r
-    UsageString = "%prog [-a ARCH] [-p PLATFORM] [-m MODULE] [-t TOOLCHAIN_TAG] [-k] [-g] [-v|-d <debug_level>|-q] [-o <output_directory>] [GenC|GenMake]"\r
-\r
-    Parser = OptionParser(description=__copyright__, version=__version__, option_list=OptionList, usage=UsageString)\r
-    Parser.set_defaults(Arch=[])\r
-    Parser.set_defaults(ActivePlatform=None)\r
-    Parser.set_defaults(ActiveModule=None)\r
-    Parser.set_defaults(OutputDirectory="build")\r
-    Parser.set_defaults(FdfFile=None)\r
-    Parser.set_defaults(ToolChain="MYTOOLS")\r
-    if sys.platform == "win32":\r
-        Parser.set_defaults(MakefileType="nmake")\r
-    else:\r
-        Parser.set_defaults(MakefileType="gmake")\r
-    Parser.set_defaults(LogLevel=EdkLogger.INFO)\r
-\r
-    Options, Args = Parser.parse_args()\r
-\r
-    # error check\r
-    if len(Args) == 0:\r
-        Options.Target = "genmake"\r
-        sys.argv.append("genmake")\r
-    elif len(Args) == 1:\r
-        Options.Target = Args[0].lower()\r
-        if Options.Target not in ["genc", "genmake"]:\r
-            EdkLogger.error("AutoGen", OPTION_NOT_SUPPORTED, "Not supported target",\r
-                            ExtraData="%s\n\n%s" % (Options.Target, Parser.get_usage()))\r
-    else:\r
-        EdkLogger.error("AutoGen", OPTION_NOT_SUPPORTED, "Too many targets",\r
-                        ExtraData=Parser.get_usage())\r
-\r
-    return Options\r
-\r
-## Entrance method\r
-#\r
-# This method mainly dispatch specific methods per the command line options.\r
-# If no error found, return zero value so the caller of this tool can know\r
-# if it's executed successfully or not.\r
-#\r
-# @retval 0     Tool was successful\r
-# @retval 1     Tool failed\r
-#\r
-def Main():\r
-    from build import build\r
-    try:\r
-        Option = GetOptions()\r
-        build.main()\r
-    except Exception, e:\r
-        print e\r
-        return 1\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 0\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
-    sys.exit(Main())\r
+    pass\r
+\r
index 499afd9..c72d75f 100644 (file)
@@ -766,26 +766,6 @@ gModuleTypeHeaderFile = {
     "USER_DEFINED"      :   [gBasicHeaderFile]\r
 }\r
 \r
-## Find value for the given GUID C name\r
-#\r
-#   @param      Packages    The list of package object\r
-#   @param      CName       The C name of the GUID\r
-#   @retval     string      The value string of given GUID\r
-#\r
-def GetGuidValue(Packages, CName):\r
-    for P in Packages:\r
-        if CName in P.Guids:\r
-            return P.Guids[CName]\r
-        if CName in P.Protocols:\r
-            return P.Protocols[CName]\r
-        if CName in P.Ppis:\r
-            return P.Ppis[CName]\r
-    else:\r
-        PackageListString = "\t" + "\n\t".join([str(P) for P in Packages])\r
-        EdkLogger.error("AutoGen", AUTOGEN_ERROR,\r
-                        "Cannot find GUID value for %s in all given packages" % CName,\r
-                        ExtraData=PackageListString)\r
-\r
 ## Create code for module PCDs\r
 #\r
 #   @param      Info        The ModuleBuildInfo object\r
@@ -794,7 +774,7 @@ def GetGuidValue(Packages, CName):
 #   @param      Pcd         The PCD object\r
 #\r
 def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):\r
-    TokenSpaceGuidValue = Info.GuidList[Pcd.TokenSpaceGuidCName]\r
+    TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue   #Info.GuidList[Pcd.TokenSpaceGuidCName]\r
     PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber\r
     #\r
     # Write PCDs\r
@@ -901,7 +881,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
     PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber\r
     TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName\r
     TokenCName  = Pcd.TokenCName\r
-    TokenSpaceGuidValue = Info.GuidList[TokenSpaceGuidCName]\r
+    TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue   #Info.GuidList[TokenSpaceGuidCName]\r
     if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:\r
         EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No generated token number for %s|%s\n" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
     TokenNumber = PcdTokenNumber[TokenCName, TokenSpaceGuidCName]\r
@@ -951,6 +931,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
         AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))\r
     if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG:\r
         AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array))\r
+        #AutoGenH.Append('#define _PCD_VALUE_%s  _gPcd_FixedAtBuild_%s\n' %(TokenCName, TokenCName))\r
         AutoGenH.Append('#define %s  %s_gPcd_FixedAtBuild_%s\n' %(GetModeName, Type, TokenCName))\r
         AutoGenH.Append('//#define %s  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)\r
 \r
@@ -1051,7 +1032,7 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
         #\r
         # TODO: need GetGuidValue() definition\r
         #\r
-        TokenSpaceGuidStructure = GetGuidValue(Platform.PackageList, TokenSpaceGuidCName)\r
+        TokenSpaceGuidStructure = Pcd.TokenSpaceGuidValue\r
         TokenSpaceGuid = GuidStructureStringToGuidValueName(TokenSpaceGuidStructure)\r
         if Pcd.Type in gDynamicExPcd:\r
             if TokenSpaceGuid not in GuidList:\r
@@ -1106,7 +1087,7 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
                 for Index in range(Dict['STRING_TABLE_VALUE'].index(VariableNameStructure)):\r
                     VariableHeadStringIndex += Dict['STRING_TABLE_LENGTH'][Index]\r
 \r
-                VariableGuidStructure = GetGuidValue(Platform.PackageList, Sku.VariableGuid)\r
+                VariableGuidStructure = Sku.VariableGuidValue\r
                 VariableGuid = GuidStructureStringToGuidValueName(VariableGuidStructure)\r
                 if VariableGuid not in GuidList:\r
                     GuidList += [VariableGuid]\r
@@ -1212,7 +1193,7 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
         if Pcd.Phase != Phase:\r
             continue\r
 \r
-        TokenSpaceGuid = GuidStructureStringToGuidValueName(GetGuidValue(Platform.PackageList, TokenSpaceGuidCName))\r
+        TokenSpaceGuid = GuidStructureStringToGuidValueName(Pcd.TokenSpaceGuidValue) #(Platform.PackageList, TokenSpaceGuidCName))\r
         GeneratedTokenNumber = Platform.PcdTokenNumber[CName, TokenSpaceGuidCName] - 1\r
         if Phase == 'DXE':\r
             GeneratedTokenNumber -= NumberOfPeiLocalTokens\r
index f96c2c5..19ac708 100755 (executable)
@@ -54,184 +54,126 @@ gIncludeMacroConversion = {
   "EFI_PPI_DEPENDENCY"              :   gPpiDefinition,\r
 }\r
 \r
-gMakefileHeader = '''#\r
-# DO NOT EDIT\r
-# This file is auto-generated by build utility\r
-#\r
-# Module Name:\r
-#\r
-#   %s\r
-#\r
-# Abstract:\r
-#\r
-#   Auto-generated makefile for building modules and libraries\r
-#\r
-'''\r
-\r
-gLibraryMakeCommand = '''@cd %(makedir)s && "$(MAKE)" $(MAKE_FLAGS) %(target)s\r
-\t@cd $(MODULE_BUILD_DIR)'''\r
-\r
 gMakeType = ""\r
 if sys.platform == "win32":\r
     gMakeType = "nmake"\r
 else:\r
     gMakeType = "gmake"\r
 \r
-gMakefileName = {"nmake" : "Makefile", "gmake" : "GNUmakefile"}\r
-\r
-gDirectorySeparator = {"nmake" : "\\", "gmake" : "/"}\r
-\r
-gCreateDirectoryCommand = {"nmake" : "mkdir", "gmake" : "mkdir -p"}\r
-gRemoveDirectoryCommand = {"nmake" : "rmdir /s /q", "gmake" : "rm -r -f"}\r
-gRemoveFileCommand = {"nmake" : "del /f /q", "gmake" : "rm -f"}\r
-gCopyFileCommand = {"nmake" : "copy /y", "gmake" : "cp -f"}\r
-gCreateDirectoryCommandTemplate = {"nmake" : 'if not exist %(dir)s mkdir %(dir)s',\r
-                                   "gmake" : "test ! -e %(dir)s && mkdir -p %(dir)s"}\r
-gRemoveDirectoryCommandTemplate = {"nmake" : 'if exist %(dir)s rmdir /s /q %(dir)s',\r
-                                   "gmake" : "test -e %(dir)s && rm -r -f %(dir)s"}\r
-\r
-#   $(CP)     copy file command\r
-#   $(MV)     move file command\r
-#   $(RM)     remove file command\r
-#   $(MD)     create dir command\r
-#   $(RD)     remove dir command\r
-#\r
-#   $(TCP)     copy file if destination file doesn't exist\r
-#   $(TMV)     move file if destination file doesn't exist\r
-#   $(TRM)     remove file if destination file exists\r
-#   $(TMD)     create dir if destination dir doesn't exist\r
-#   $(TRD)     remove dir if destination dir exists\r
-gShellCommand = {\r
-    "nmake" : {\r
-        "CP"    :   "copy /y",\r
-        "MV"    :   "move /y",\r
-        "RM"    :   "del /f /q",\r
-        "MD"    :   "mkdir",\r
-        "RD"    :   "rmdir /s /q",\r
-    },\r
-\r
-    "gmake" : {\r
-        "CP"    :   "cp -f",\r
-        "MV"    :   "mv -f",\r
-        "RM"    :   "rm -f",\r
-        "MD"    :   "mkdir -p",\r
-        "RD"    :   "rm -r -f",\r
-    }\r
-}\r
-gIncludeFlag = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I"}\r
-\r
-gStartGroupFlag = {"MSFT" : "", "GCC" : "-(", "INTEL" : ""}\r
-gEndGroupFlag = {"MSFT" : "", "GCC" : "-)", "INTEL" : ""}\r
-\r
-gCustomMakefileTemplate = '''\\r
-${makefile_header}\r
-\r
-#\r
-# Platform Macro Definition\r
-#\r
-PLATFORM_NAME = ${platform_name}\r
-PLATFORM_GUID = ${platform_guid}\r
-PLATFORM_VERSION = ${platform_version}\r
-PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
-PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
-PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
-\r
-#\r
-# Module Macro Definition\r
-#\r
-MODULE_NAME = ${module_name}\r
-MODULE_GUID = ${module_guid}\r
-MODULE_VERSION = ${module_version}\r
-MODULE_TYPE = ${module_type}\r
-MODULE_FILE_BASE_NAME = ${module_file_base_name}\r
-BASE_NAME = $(MODULE_NAME)\r
-MODULE_RELATIVE_DIR = ${module_relative_directory}\r
-MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}\r
-\r
-#\r
-# Build Configuration Macro Definition\r
-#\r
-ARCH = ${architecture}\r
-TOOLCHAIN_TAG = ${toolchain_tag}\r
-TARGET = ${build_target}\r
-\r
-#\r
-# Build Directory Macro Definition\r
-#\r
-# PLATFORM_BUILD_DIR = ${platform_build_directory}\r
-BUILD_DIR = ${platform_build_directory}\r
-BIN_DIR = $(BUILD_DIR)${separator}${architecture}\r
-LIB_DIR = $(BIN_DIR)\r
-MODULE_BUILD_DIR = $(BUILD_DIR)${separator}${architecture}${separator}${module_relative_directory}${separator}${module_file_base_name}\r
-OUTPUT_DIR = $(MODULE_BUILD_DIR)${separator}OUTPUT\r
-DEBUG_DIR = $(MODULE_BUILD_DIR)${separator}DEBUG\r
-DEST_DIR_OUTPUT = $(OUTPUT_DIR)\r
-DEST_DIR_DEBUG = $(DEBUG_DIR)\r
-\r
-#\r
-# Default Tools Flags Macro Definition (from tools_def.txt by default)\r
-#\r
-${BEGIN}DEFAULT_${tool_code}_FLAGS = ${default_tool_flags}\r
-${END}\r
-\r
-#\r
-# Platform Tools Flags Macro Definition (from platform description file)\r
-#\r
-${BEGIN}PLATFORM_${tool_code}_FLAGS = ${platform_tool_flags}\r
-${END}\r
 \r
+## BuildFile class\r
 #\r
-# Module Tools Flags Macro Definition (from platform/module description file)\r
+#  This class encapsules makefie and its generation. It uses template to generate\r
+#  the content of makefile. The content of makefile will be got from PlatformBuildInfo\r
+#  or ModuleBuildInfo objects.\r
 #\r
-${BEGIN}MODULE_${tool_code}_FLAGS = ${module_tool_flags}\r
-${END}\r
+class BuildFile(object):\r
+    _TEMPLATE_ = ''\r
+    _FILE_NAME_ = {\r
+        "nmake" :   "Makefile",\r
+        "gmake" :   "GNUmakefile"\r
+    }\r
 \r
+    _MAKEFILE_HEADER = '''#\r
+# DO NOT EDIT\r
+# This file is auto-generated by build utility\r
 #\r
-# Tools Flag Macro\r
-#\r
-${BEGIN}${tool_code}_FLAGS = $(DEFAULT_${tool_code}_FLAGS) $(PLATFORM_${tool_code}_FLAGS) $(MODULE_${tool_code}_FLAGS)\r
-${END}\r
-\r
+# Module Name:\r
 #\r
-# Tools Path Macro\r
+#   %s\r
 #\r
-${BEGIN}${tool_code} = ${tool_path}\r
-${END}\r
-\r
-MAKE_FILE = ${makefile_path}\r
-\r
+# Abstract:\r
 #\r
-# Shell Command Macro\r
+#   Auto-generated makefile for building modules, libraries or platform\r
 #\r
-${BEGIN}${shell_command_code} = ${shell_command}\r
-${END}\r
+    '''\r
+    \r
+    _FILE_HEADER_ = {\r
+        "nmake" :   _MAKEFILE_HEADER % _FILE_NAME_["nmake"],\r
+        "gmake" :   _MAKEFILE_HEADER % _FILE_NAME_["gmake"]\r
+    }\r
 \r
-${custom_makefile_content}\r
+    #   \r
+    #   $(CP)     copy file command\r
+    #   $(MV)     move file command\r
+    #   $(RM)     remove file command\r
+    #   $(MD)     create dir command\r
+    #   $(RD)     remove dir command\r
+    #\r
+    _SHELL_CMD_ = {\r
+        "nmake" : {\r
+            "CP"    :   "copy /y",\r
+            "MV"    :   "move /y",\r
+            "RM"    :   "del /f /q",\r
+            "MD"    :   "mkdir",\r
+            "RD"    :   "rmdir /s /q",\r
+        },\r
+    \r
+        "gmake" : {\r
+            "CP"    :   "cp -f",\r
+            "MV"    :   "mv -f",\r
+            "RM"    :   "rm -f",\r
+            "MD"    :   "mkdir -p",\r
+            "RD"    :   "rm -r -f",\r
+        }\r
+    }\r
 \r
-#\r
-# Target used when called from platform makefile, which will bypass the build of dependent libraries\r
-#\r
+    _SEP_ = {\r
+        "nmake" :   "\\", \r
+        "gmake" :   "/"\r
+    }\r
+    \r
+    _MD_TEMPLATE_ = {\r
+        "nmake" :   'if not exist %(dir)s $(MD) %(dir)s',\r
+        "gmake" :   "test ! -e %(dir)s && $(MD) %(dir)s"\r
+    }\r
 \r
-pbuild: init all\r
+    _RD_TEMPLATE_ = {\r
+        "nmake" :   'if exist %(dir)s $(RD) %(dir)s',\r
+        "gmake" :   "test -e %(dir)s && $(RD) %(dir)s"\r
+    }\r
+    \r
+    _INC_FLAG_ = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I"}\r
+    \r
+    _LIB_GROUP_START_ = {"MSFT" : "", "GCC" : "-(", "INTEL" : ""}\r
+    _LIB_GROUP_END = {"MSFT" : "", "GCC" : "-)", "INTEL" : ""}\r
+    \r
 \r
+    def __init__(self, AutoGenObject):\r
+        self._AutoGenObject = AutoGenObject\r
+        self._FileType = gMakeType\r
 \r
-#\r
-# ModuleTarget\r
-#\r
+    def Generate(self, FileType=gMakeType):\r
+        self._FileType = FileType\r
+        FileContent = TemplateString()\r
+        FileContent.Append(self._TEMPLATE_, self._TemplateDict)\r
 \r
-mbuild: init all\r
+        FileName = self._FILE_NAME_[FileType]\r
+        return SaveFileOnChange(os.path.join(self._AutoGenObject.MakeFileDir, FileName), str(FileContent))\r
 \r
+    ## Return a list of directory creation command string\r
+    #\r
+    #   @param      DirList     The list of directory to be created\r
+    #   @param      MakeType    GNU makefile or MS makefile\r
+    #\r
+    #   @retval     list        The directory creation command list\r
+    #\r
+    def GetCreateDirectoryCommand(self, DirList):\r
+        return [self._MD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]\r
 \r
-#\r
-# Initialization target: print build information and create necessary directories\r
-#\r
-init:\r
-\t-@echo Building ... $(MODULE_NAME) $(MODULE_VERSION) [$(ARCH)] in platform $(PLATFORM_NAME) $(PLATFORM_VERSION)\r
-${BEGIN}\t-@${create_directory_command}\n${END}\\r
+    ## Return a list of directory removal command string\r
+    #\r
+    #   @param      DirList     The list of directory to be removed\r
+    #   @param      MakeType    GNU makefile or MS makefile\r
+    #\r
+    #   @retval     list        The directory removal command list\r
+    #\r
+    def GetRemoveDirectoryCommand(self, DirList):\r
+        return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]\r
 \r
-'''\r
 \r
-gModuleMakefileTemplate = '''\\r
+class ModuleMakefile(BuildFile):\r
+    _TEMPLATE_ = '''\\r
 ${makefile_header}\r
 \r
 #\r
@@ -277,27 +219,9 @@ DEST_DIR_OUTPUT = $(OUTPUT_DIR)
 DEST_DIR_DEBUG = $(DEBUG_DIR)\r
 \r
 #\r
-# Default Tools Flags Macro Definition (from tools_def.txt by default)\r
-#\r
-${BEGIN}DEFAULT_${tool_code}_FLAGS = ${default_tool_flags}\r
-${END}\r
-\r
-#\r
-# Platform Tools Flags Macro Definition (from platform description file)\r
-#\r
-${BEGIN}PLATFORM_${tool_code}_FLAGS = ${platform_tool_flags}\r
-${END}\r
-\r
-#\r
-# Module Tools Flags Macro Definition (from platform/module description file)\r
-#\r
-${BEGIN}MODULE_${tool_code}_FLAGS = ${module_tool_flags}\r
-${END}\r
-\r
-#\r
-# Tools Flag Macro\r
+# Tools Flag Macro (from platform/module description file, tools_def.txt)\r
 #\r
-${BEGIN}${tool_code}_FLAGS = $(DEFAULT_${tool_code}_FLAGS) $(PLATFORM_${tool_code}_FLAGS) $(MODULE_${tool_code}_FLAGS)\r
+${BEGIN}${tool_code}_FLAGS = ${module_tool_flags}\r
 ${END}\r
 \r
 #\r
@@ -333,7 +257,7 @@ INC = ${BEGIN}${include_path_prefix}${include_path} \\
 #OBJECTS = ${BEGIN}$(OUTPUT_DIR)${separator}${object_file} \\\r
 #          ${END}\r
 \r
-LIBS = ${BEGIN}$(BUILD_DIR)${separator}$(ARCH)${separator}${library_file} \\\r
+LIBS = ${BEGIN}${library_file} \\\r
        ${END}${BEGIN}${system_library} \\\r
        ${END} \\\r
        $(LIB_LIST)\r
@@ -356,7 +280,7 @@ CODA_TARGET = ${BEGIN}${remaining_build_target} \\
 # Default target, which will build dependent libraries in addition to source files\r
 #\r
 \r
-all: ${build_type}\r
+all: mbuild\r
 \r
 \r
 #\r
@@ -382,7 +306,7 @@ fds: mbuild gen_fds
 # Initialization target: print build information and create necessary directories\r
 #\r
 init:\r
-\t-@echo Building ... $(MODULE_NAME) $(MODULE_VERSION) [$(ARCH)] in platform $(PLATFORM_NAME) $(PLATFORM_VERSION)\r
+\t-@echo Building ... $(MODULE_NAME) [$(ARCH)]\r
 ${BEGIN}\t-@${create_directory_command}\n${END}\\r
 ${BEGIN}\t-@${copy_autogen_h}\n${END}\r
 \r
@@ -390,7 +314,7 @@ ${BEGIN}\t-@${copy_autogen_h}\n${END}
 # GenLibsTarget\r
 #\r
 gen_libs:\r
-\t${BEGIN}@cd $(BUILD_DIR)${separator}$(ARCH)${separator}${dependent_library_build_directory} && "$(MAKE)" $(MAKE_FLAGS)\r
+\t${BEGIN}@cd ${dependent_library_build_directory} && "$(MAKE)" $(MAKE_FLAGS)\r
 \t${END}@cd $(MODULE_BUILD_DIR)\r
 \r
 #\r
@@ -436,449 +360,153 @@ cleanpch:
 #\r
 \r
 cleanlib:\r
-\t${BEGIN}@cd $(BUILD_DIR)${separator}$(ARCH)${separator}${dependent_library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) cleanall\r
-\t${END}@cd $(MODULE_BUILD_DIR)\r
+\t${BEGIN}@cd ${dependent_library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) cleanall\r
+\t${END}@cd $(MODULE_BUILD_DIR)\n'''\r
+    \r
+    def __init__(self, ModuleAutoGen):\r
+        BuildFile.__init__(self, ModuleAutoGen)\r
+        self.PlatformInfo = self._AutoGenObject.PlatformInfo\r
+\r
+        self.ResultFileList = []\r
+        self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]\r
+    \r
+        self.SourceFileDatabase = {}  # {file type : file path}\r
+        self.DestFileDatabase = {}  # {file type : file path}\r
+        self.FileBuildTargetList = [] # [(src, target string)]\r
+        self.BuildTargetList = [] # [target string]\r
+        self.PendingBuildTargetList = [] # [FileBuildRule objects]\r
+        self.CommonFileDependency = []\r
+\r
+        self.FileDependency = []\r
+        self.LibraryBuildCommandList = []\r
+        self.LibraryFileList = []\r
+        self.LibraryMakefileList = []\r
+        self.LibraryBuildDirectoryList = []\r
+        self.SystemLibraryList = []\r
+\r
+    def _CreateTemplateDict(self):\r
+        if self._FileType not in self._SEP_:\r
+            EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type", ExtraData=self._FileType)\r
+        Separator = self._SEP_[self._FileType]\r
 \r
-'''\r
+        # break build if no source files and binary files are found\r
+        if len(self._AutoGenObject.SourceFileList) == 0 and len(self._AutoGenObject.BinaryFileDict) == 0:\r
+            EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"\r
+                            % (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch),\r
+                            ExtraData=str(self._AutoGenObject))\r
+        # convert source files and binary files to build target\r
+        if len(self._AutoGenObject.SourceFileList) > 0:\r
+            self.ProcessSourceFileList()\r
+        if len(self._AutoGenObject.BinaryFileDict) > 0:\r
+            self.ProcessBinaryFileList()\r
 \r
-gPlatformMakefileTemplate = '''\\r
-${makefile_header}\r
+        # convert dependent libaries to build command\r
+        self.ProcessDependentLibrary()\r
+        if self._AutoGenObject.Arch == "EBC":\r
+            # EBC compiler always use "EfiStart" as entry point\r
+            EntryPoint = "EfiStart"\r
+        elif self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.Module.ModuleEntryPointList) > 0:\r
+            # R8 modules use different entry point functions\r
+            EntryPoint = self._AutoGenObject.Module.ModuleEntryPointList[0]\r
+        else:\r
+            # R9 modules always use "_ModuleEntryPoint" as entry point\r
+            EntryPoint = "_ModuleEntryPoint"\r
 \r
-#\r
-# Platform Macro Definition\r
-#\r
-PLATFORM_NAME = ${platform_name}\r
-PLATFORM_GUID = ${platform_guid}\r
-PLATFORM_VERSION = ${platform_version}\r
-PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
-PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
+        DefaultToolFlag = self.PlatformInfo.ToolOption.values()\r
+        # USER_DEFINED modules should take care of tools definitions by its own\r
+        if self._AutoGenObject.ModuleType == "USER_DEFINED":\r
+            DefaultToolFlag = ["" for p in DefaultToolFlag]\r
 \r
-#\r
-# Build Configuration Macro Definition\r
-#\r
-TOOLCHAIN_TAG = ${toolchain_tag}\r
-TARGET = ${build_target}\r
+        if "CC" not in self.PlatformInfo.ToolChainFamily:\r
+            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [CC] is not supported [%s, %s, %s]" % (self._AutoGenObject.BuildTarget,\r
+                                    self._AutoGenObject.ToolChain, self._AutoGenObject.Arch))\r
+        if  "DLINK" not in self.PlatformInfo.ToolChainFamily:\r
+            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [DLINK] is not supported [%s, %s, %s]" % (self._AutoGenObject.BuildTarget,\r
+                                    self._AutoGenObject.ToolChain, self._AutoGenObject.Arch))\r
 \r
-#\r
-# Build Directory Macro Definition\r
-#\r
-BUILD_DIR = ${platform_build_directory}\r
-FV_DIR = ${platform_build_directory}${separator}FV\r
+        if self._AutoGenObject.IsLibrary:\r
+            if "Static-Library-File" in self.DestFileDatabase:\r
+                self.ResultFileList = self.DestFileDatabase["Static-Library-File"]\r
+        elif self._AutoGenObject.ModuleType == "USER_DEFINED":\r
+            if "Dynamic-Library-File" in self.DestFileDatabase:\r
+                self.ResultFileList = self.DestFileDatabase["Dynamic-Library-File"]\r
+        if len(self.ResultFileList) == 0:\r
+            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Don't know how to end the module build")\r
 \r
-#\r
-# Shell Command Macro\r
-#\r
-${BEGIN}${shell_command_code} = ${shell_command}\r
-${END}\r
+        SourceFileMacroNameList = []\r
+        SourceFileMacroList = [] # macro name = file list\r
+        for FileType in self.SourceFileDatabase:\r
+            Macro = "%s_LIST" % FileType.replace("-", "_").upper()\r
+            SourceFileMacroNameList.append("$(%s)" % Macro)\r
+            Template = TemplateString()\r
+            Template.Append("%s = ${BEGIN}${source_file} \\\n\t${END}" % Macro,\r
+                            {"source_file" : self.SourceFileDatabase[FileType]})\r
+            SourceFileMacroList.append(str(Template))\r
+        TargetFileMacroList = []\r
+        TargetFileMacroNameList = []\r
+        for FileType in self.DestFileDatabase:\r
+            Macro = "%s_LIST" % FileType.replace("-", "_").upper()\r
+            TargetFileMacroNameList.append("$(%s)" % Macro)\r
+            Template = TemplateString()\r
+            Template.Append("%s = ${BEGIN}${target_file} \\\n\t${END}" % Macro,\r
+                            {"target_file" : self.DestFileDatabase[FileType]})\r
+            TargetFileMacroList.append(str(Template))\r
 \r
-MAKE = ${make_path}\r
-MAKE_FLAGS = ${make_flag}\r
-MAKE_FILE = ${makefile_path}\r
+        # R8 modules need <BaseName>StrDefs.h for string ID\r
+        if self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.UnicodeFileList) > 0:\r
+            AutoGenHeaderFile = os.path.join("$(DEBUG_DIR)", "AutoGen.h")\r
+            StringHeaderFile = os.path.join("$(DEBUG_DIR)", "%sStrDefs.h" % self._AutoGenObject.Name)\r
+            CopyAutoGenHeaderFile = ["$(CP) %s %s" % (AutoGenHeaderFile, StringHeaderFile)]\r
+        else:\r
+            CopyAutoGenHeaderFile = []\r
 \r
-#\r
-# Default target\r
-#\r
-all: init build_libraries build_modules build_fds\r
+        MakefileName = self._FILE_NAME_[self._FileType]\r
+        MakefileTemplateDict = {\r
+            "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
+            "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),\r
+            "platform_name"             : self.PlatformInfo.Name,\r
+            "platform_guid"             : self.PlatformInfo.Guid,\r
+            "platform_version"          : self.PlatformInfo.Version,\r
+            "platform_relative_directory": self.PlatformInfo.SourceDir,\r
+            "platform_output_directory" : self.PlatformInfo.OutputDir,\r
 \r
-#\r
-# Initialization target: print build information and create necessary directories\r
-#\r
-init:\r
-\t-@echo Building ... $(PLATFORM_NAME) $(PLATFORM_VERSION) [${build_architecture_list}]\r
-\t${BEGIN}-@${create_directory_command}\r
-\t${END}\r
-#\r
-# library build target\r
-#\r
-libraries: init build_libraries\r
+            "module_name"               : self._AutoGenObject.Name,\r
+            "module_guid"               : self._AutoGenObject.Guid,\r
+            "module_version"            : self._AutoGenObject.Version,\r
+            "module_type"               : self._AutoGenObject.ModuleType,\r
+            "module_file_base_name"     : self._AutoGenObject.FileBase,\r
+            "module_relative_directory" : self._AutoGenObject.SourceDir,\r
 \r
-#\r
-# module build target\r
-#\r
-modules: init build_libraries build_modules\r
+            "architecture"              : self._AutoGenObject.Arch,\r
+            "toolchain_tag"             : self._AutoGenObject.ToolChain,\r
+            "build_target"              : self._AutoGenObject.BuildTarget,\r
 \r
-#\r
-# Flash Device Image Target\r
-#\r
-fds: init build_fds\r
+            "platform_build_directory"  : self.PlatformInfo.BuildDir,\r
 \r
-#\r
-# Build all libraries:\r
-#\r
-build_libraries:\r
-${BEGIN}\t@cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) pbuild\r
-${END}\t@cd $(BUILD_DIR)\r
+            "separator"                 : Separator,\r
+            "module_tool_flags"         : [self._AutoGenObject.BuildOption[tool] for tool in self.PlatformInfo.ToolPath],\r
 \r
-#\r
-# Build all modules:\r
-#\r
-build_modules:\r
-${BEGIN}\t@cd ${module_build_directory} && "$(MAKE)" $(MAKE_FLAGS) pbuild\r
-${END}\t@cd $(BUILD_DIR)\r
+            "tool_code"                 : self.PlatformInfo.ToolPath.keys(),\r
+            "tool_path"                 : self.PlatformInfo.ToolPath.values(),\r
 \r
-#\r
-# Build Flash Device Image\r
-#\r
-build_fds:\r
-\t-@cd $(FV_DIR)\r
-${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN_TAG) -b $(TARGET) -p ${active_platform} -a ${build_architecture_list} ${log_level}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -y ${macro} ${END}\r
-\r
-#\r
-# run command for emulator platform only\r
-#\r
-run:\r
-\tcd $(BUILD_DIR)${separator}IA32\r
-\tSecMain\r
-\tcd $(BUILD_DIR)\r
-\r
-#\r
-# Clean intermediate files\r
-#\r
-clean:\r
-\t${BEGIN}@cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) clean\r
-\t${END}${BEGIN}@cd ${module_build_directory} && "$(MAKE)" $(MAKE_FLAGS) clean\r
-\t${END}@cd $(BUILD_DIR)\r
-\r
-#\r
-# Clean all generated files except to makefile\r
-#\r
-cleanall:\r
-${BEGIN}\t${cleanall_command}\r
-${END}\r
-\r
-#\r
-# Clean all library files\r
-#\r
-cleanlib:\r
-\t${BEGIN}@cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) cleanall\r
-\t${END}@cd $(BUILD_DIR)\r
-\r
-'''\r
-\r
-## Makefile class\r
-#\r
-#  This class encapsules makefie and its generation. It uses template to generate\r
-#  the content of makefile. The content of makefile will be got from PlatformBuildInfo\r
-#  or ModuleBuildInfo objects.\r
-#\r
-class Makefile(object):\r
-    ## Constructor\r
-    #\r
-    #  Intitialize the data member simply\r
-    #\r
-    #   @param      Info    PlatformBuildInfo or ModuleBuildInfo object\r
-    #   @param      Option  Option for the makefile generation (not used)\r
-    #\r
-    def __init__(self, Info, Option=None):\r
-        if isinstance(Info, ModuleBuildInfo):\r
-            if Info == None or Info == "":\r
-                EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No valid module found! Please check your build configuration!\n")\r
-            self.ModuleInfo = Info\r
-            self.PlatformInfo = Info.PlatformInfo\r
-            self.ModuleBuild = True\r
-\r
-            self.BuildType = "mbuild"\r
-            self.TargetFileList = []\r
-            self.ObjectFileList = []\r
-\r
-            self.ResultFileList = []\r
-            self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]\r
-\r
-            self.SourceFileDatabase = {}  # {file type : file path}\r
-            self.DestFileDatabase = {}  # {file type : file path}\r
-            self.FileBuildTargetList = [] # [(src, target string)]\r
-            self.BuildTargetList = [] # [target string]\r
-            self.PendingBuildTargetList = [] # [FileBuildRule objects]\r
-            self.CommonFileDependency = []\r
-\r
-            self.FileDependency = []\r
-            self.LibraryBuildCommandList = []\r
-            self.LibraryFileList = []\r
-            self.LibraryMakefileList = []\r
-            self.LibraryBuildDirectoryList = []\r
-            self.SystemLibraryList = []\r
-        elif type(Info) == type({}):    # and isinstance(info, PlatformBuildInfo):\r
-            if len(Info) <= 0:\r
-                EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No buildable platform found! Please check your build configuration!\n")\r
-            self.PlatformInfo = Info\r
-            self.ModuleBuild = False\r
-            self.ModuleBuildCommandList = []\r
-            self.ModuleMakefileList = []\r
-            self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()\r
-            self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()\r
-        else:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Non-buildable item:%s" % str(Info))\r
-\r
-        self.IntermediateDirectoryList = []\r
-\r
-    ## Create necessary directory for makefile generation\r
-    def PrepareDirectory(self):\r
-        if self.ModuleBuild:\r
-            if not CreateDirectory(self.PlatformInfo.BuildDir):\r
-                EdkLogger.error("AutoGen", FILE_CREATE_FAILURE, ExtraData=self.PlatformInfo.BuildDir)\r
-            if not CreateDirectory(self.ModuleInfo.BuildDir):\r
-                EdkLogger.error("AutoGen", FILE_CREATE_FAILURE, ExtraData=self.ModuleInfo.BuildDir)\r
-            if not CreateDirectory(self.ModuleInfo.DebugDir):\r
-                EdkLogger.error("AutoGen", FILE_CREATE_FAILURE, ExtraData=self.ModuleInfo.DebugDir)\r
-\r
-    ## Create the makefile\r
-    #\r
-    #   @param      File        The path of the makefile\r
-    #   @param      MakeType    GNU makefile or MS makefile\r
-    #\r
-    #   @retval     True        If the file is changed or doesn't exist\r
-    #   @retval     False       If the file exists and its content is not changed\r
-    #                           since last time\r
-    #\r
-    def Generate(self, File=None, MakeType=gMakeType):\r
-        if self.ModuleBuild:\r
-            return self.GenerateModuleMakefile(File, MakeType)\r
-        else:\r
-            return self.GeneratePlatformMakefile(File, MakeType)\r
-\r
-    ## Create makefile of platform\r
-    #\r
-    #   @param      File        The path of the makefile\r
-    #   @param      MakeType    GNU makefile or MS makefile\r
-    #\r
-    #   @retval     True        If the file is changed or doesn't exist\r
-    #   @retval     False       If the file exists and its content is not changed\r
-    #                           since last time\r
-    #\r
-    def GeneratePlatformMakefile(self, File=None, MakeType=gMakeType):\r
-        if MakeType not in gDirectorySeparator:\r
-            EdkLogger.error("GenMake", PARAMETER_INVALID, "Invalid Makefile type", ExtraData=MakeType)\r
-        Separator = gDirectorySeparator[MakeType]\r
-\r
-        ArchList = self.PlatformInfo.keys()\r
-        PlatformInfo = self.PlatformInfo.values()[0]\r
-        ActivePlatform = PlatformInfo.Platform\r
-\r
-        if "MAKE" not in PlatformInfo.ToolPath:\r
-            EdkLogger.error("GenMake", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!")\r
-\r
-        self.IntermediateDirectoryList = ["$(BUILD_DIR)%s%s" % (Separator, Arch) for Arch in self.PlatformInfo]\r
-        self.IntermediateDirectoryList.append("$(FV_DIR)")\r
-\r
-        # TRICK: for not generating GenFds call in makefile if no FDF file\r
-        MacroList = []\r
-        if PlatformInfo.FdfFile != None and PlatformInfo.FdfFile != "":\r
-            FdfFileList = [PlatformInfo.FdfFile]\r
-            # macros passed to GenFds\r
-            for MacroName in GlobalData.gGlobalDefines:\r
-                MacroList.append('"%s=%s"' % (MacroName, GlobalData.gGlobalDefines[MacroName]))\r
-        else:\r
-            FdfFileList = []\r
-\r
-        # pass log level to external program called in makefile, currently GenFds.exe\r
-        LogLevel = EdkLogger.GetLevel()\r
-        if LogLevel == EdkLogger.VERBOSE:\r
-            LogOption = "-v"\r
-        elif LogLevel <= EdkLogger.DEBUG_9:\r
-            LogOption = "-d %d" % (LogLevel - 1)\r
-        elif LogLevel == EdkLogger.QUIET:\r
-            LogOption = "-q"\r
-        else:\r
-            LogOption = ""\r
-\r
-        MakefileName = gMakefileName[MakeType]\r
-        MakefileTemplateDict = {\r
-            "makefile_header"           : gMakefileHeader % MakefileName,\r
-            "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),\r
-            "platform_name"             : PlatformInfo.Name,\r
-            "platform_guid"             : PlatformInfo.Guid,\r
-            "platform_version"          : PlatformInfo.Version,\r
-            "platform_relative_directory": PlatformInfo.SourceDir,\r
-            "platform_output_directory" : PlatformInfo.OutputDir,\r
-            "platform_build_directory"  : PlatformInfo.BuildDir,\r
-\r
-            "toolchain_tag"             : PlatformInfo.ToolChain,\r
-            "build_target"              : PlatformInfo.BuildTarget,\r
-            "make_path"                 : PlatformInfo.ToolPath["MAKE"],\r
-            "make_flag"                 : PlatformInfo.ToolOption["MAKE"],\r
-            "shell_command_code"        : gShellCommand[MakeType].keys(),\r
-            "shell_command"             : gShellCommand[MakeType].values(),\r
-            "build_architecture_list"   : ",".join(ArchList),\r
-            "architecture"              : self.PlatformInfo.keys(),\r
-            "separator"                 : Separator,\r
-            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList, MakeType),\r
-            "remove_directory_command"  : gRemoveDirectoryCommand[MakeType],\r
-            "remove_file_command"       : gRemoveFileCommand[MakeType],\r
-            "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList, MakeType),\r
-            "library_build_directory"   : self.LibraryBuildDirectoryList,\r
-            "module_build_directory"    : self.ModuleBuildDirectoryList,\r
-            "fdf_file"                  : FdfFileList,\r
-            "active_platform"           : PlatformInfo.WorkspaceDir + Separator + ActivePlatform.DescFilePath,\r
-            "fd"                        : PlatformInfo.FdTargetList,\r
-            "fv"                        : PlatformInfo.FvTargetList,\r
-            "log_level"                 : LogOption,\r
-            "macro"                     : MacroList,\r
-        }\r
-\r
-        self.PrepareDirectory()\r
-\r
-        AutoGenMakefile = TemplateString()\r
-        AutoGenMakefile.Append(gPlatformMakefileTemplate, MakefileTemplateDict)\r
-\r
-        FilePath = ""\r
-        if File == None:\r
-            os.chdir(PlatformInfo.MakeFileDir)\r
-            FilePath = MakefileName\r
-        else:\r
-            FilePath = File\r
-\r
-        Result = SaveFileOnChange(FilePath, str(AutoGenMakefile))\r
-        os.chdir(PlatformInfo.WorkspaceDir)\r
-        return Result\r
-\r
-    ## Create makefile of a module\r
-    #\r
-    #   @param      File        The path of the makefile\r
-    #   @param      MakeType    GNU makefile or MS makefile\r
-    #\r
-    #   @retval     True        If the file is changed or doesn't exist\r
-    #   @retval     False       If the file exists and its content is not changed\r
-    #                           since last time\r
-    #\r
-    def GenerateModuleMakefile(self, File=None, MakeType=gMakeType):\r
-        if MakeType in self.ModuleInfo.CustomMakefile and self.ModuleInfo.CustomMakefile[MakeType] != "":\r
-            return self.GenerateCustomBuildMakefile(File, MakeType)\r
-\r
-        if MakeType not in gDirectorySeparator:\r
-            EdkLogger.error("GenMake", PARAMETER_INVALID, "Invalid Makefile type", ExtraData=MakeType)\r
-        Separator = gDirectorySeparator[MakeType]\r
-        PlatformInfo = self.PlatformInfo\r
-\r
-        # break build if no source files and binary files are found\r
-        if len(self.ModuleInfo.SourceFileList) == 0 and len(self.ModuleInfo.BinaryFileDict) == 0:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"\r
-                            % (self.ModuleInfo.BuildTarget, self.ModuleInfo.ToolChain, self.ModuleInfo.Arch),\r
-                            ExtraData=str(self.ModuleInfo.Module))\r
-        # convert source files and binary files to build target\r
-        if len(self.ModuleInfo.SourceFileList) > 0:\r
-            self.ProcessSourceFileList(MakeType)\r
-        if len(self.ModuleInfo.BinaryFileDict) > 0:\r
-            self.ProcessBinaryFileList(MakeType)\r
-        # convert dependent libaries to build command\r
-        self.ProcessDependentLibrary(MakeType)\r
-\r
-        if "DLINK" in PlatformInfo.ToolStaticLib:\r
-            EdkLogger.debug(EdkLogger.DEBUG_5, "Static library: " + PlatformInfo.ToolStaticLib["DLINK"])\r
-            self.SystemLibraryList.append(PlatformInfo.ToolStaticLib["DLINK"])\r
-\r
-        if self.ModuleInfo.Arch == "EBC":\r
-            # EBC compiler always use "EfiStart" as entry point\r
-            EntryPoint = "EfiStart"\r
-        elif self.ModuleInfo.AutoGenVersion < 0x00010005 and len(self.ModuleInfo.Module.ModuleEntryPointList) > 0:\r
-            # R8 modules use different entry point functions\r
-            EntryPoint = self.ModuleInfo.Module.ModuleEntryPointList[0]\r
-        else:\r
-            # R9 modules always use "_ModuleEntryPoint" as entry point\r
-            EntryPoint = "_ModuleEntryPoint"\r
-\r
-        DefaultToolFlag = PlatformInfo.ToolOption.values()\r
-        # USER_DEFINED modules should take care of tools definitions by its own\r
-        if self.ModuleInfo.ModuleType == "USER_DEFINED":\r
-            DefaultToolFlag = ["" for p in DefaultToolFlag]\r
-\r
-        if "CC" not in PlatformInfo.ToolChainFamily:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [CC] is not supported [%s, %s, %s]" % (self.ModuleInfo.BuildTarget,\r
-                                    self.ModuleInfo.ToolChain, self.ModuleInfo.Arch))\r
-        if  "DLINK" not in PlatformInfo.ToolChainFamily:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [DLINK] is not supported [%s, %s, %s]" % (self.ModuleInfo.BuildTarget,\r
-                                    self.ModuleInfo.ToolChain, self.ModuleInfo.Arch))\r
-\r
-        if self.ModuleInfo.IsLibrary:\r
-            if "Static-Library-File" in self.DestFileDatabase:\r
-                self.ResultFileList = self.DestFileDatabase["Static-Library-File"]\r
-        elif self.ModuleInfo.ModuleType == "USER_DEFINED":\r
-            if "Dynamic-Library-File" in self.DestFileDatabase:\r
-                self.ResultFileList = self.DestFileDatabase["Dynamic-Library-File"]\r
-        if len(self.ResultFileList) == 0:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Don't know how to end the module build")\r
-\r
-        SourceFileMacroNameList = []\r
-        SourceFileMacroList = [] # macro name = file list\r
-        for FileType in self.SourceFileDatabase:\r
-            Macro = "%s_LIST" % FileType.replace("-", "_").upper()\r
-            SourceFileMacroNameList.append("$(%s)" % Macro)\r
-            Template = TemplateString()\r
-            Template.Append("%s = ${BEGIN}${source_file} \\\n\t${END}" % Macro,\r
-                            {"source_file" : self.SourceFileDatabase[FileType]})\r
-            SourceFileMacroList.append(str(Template))\r
-        TargetFileMacroList = []\r
-        TargetFileMacroNameList = []\r
-        for FileType in self.DestFileDatabase:\r
-            Macro = "%s_LIST" % FileType.replace("-", "_").upper()\r
-            TargetFileMacroNameList.append("$(%s)" % Macro)\r
-            Template = TemplateString()\r
-            Template.Append("%s = ${BEGIN}${target_file} \\\n\t${END}" % Macro,\r
-                            {"target_file" : self.DestFileDatabase[FileType]})\r
-            TargetFileMacroList.append(str(Template))\r
-\r
-        # R8 modules need <BaseName>StrDefs.h for string ID\r
-        if self.ModuleInfo.AutoGenVersion < 0x00010005 and len(self.ModuleInfo.UnicodeFileList) > 0:\r
-            AutoGenHeaderFile = os.path.join("$(DEBUG_DIR)", "AutoGen.h")\r
-            StringHeaderFile = os.path.join("$(DEBUG_DIR)", "%sStrDefs.h" % self.ModuleInfo.BaseName)\r
-            CopyAutoGenHeaderFile = ["$(CP) %s %s" % (AutoGenHeaderFile, StringHeaderFile)]\r
-        else:\r
-            CopyAutoGenHeaderFile = []\r
-\r
-        MakefileName = gMakefileName[MakeType]\r
-        MakefileTemplateDict = {\r
-            "makefile_header"           : gMakefileHeader % MakefileName,\r
-            "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),\r
-            "platform_name"             : PlatformInfo.Name,\r
-            "platform_guid"             : PlatformInfo.Guid,\r
-            "platform_version"          : PlatformInfo.Version,\r
-            "platform_relative_directory": PlatformInfo.SourceDir,\r
-            "platform_output_directory" : PlatformInfo.OutputDir,\r
-\r
-            "module_name"               : self.ModuleInfo.Name,\r
-            "module_guid"               : self.ModuleInfo.Guid,\r
-            "module_version"            : self.ModuleInfo.Version,\r
-            "module_type"               : self.ModuleInfo.ModuleType,\r
-            "module_file_base_name"     : self.ModuleInfo.FileBase,\r
-            "module_relative_directory" : self.ModuleInfo.SourceDir,\r
-\r
-            "architecture"              : self.ModuleInfo.Arch,\r
-            "toolchain_tag"             : self.ModuleInfo.ToolChain,\r
-            "build_target"              : self.ModuleInfo.BuildTarget,\r
-\r
-            "platform_build_directory"  : PlatformInfo.BuildDir,\r
-\r
-            "separator"                 : Separator,\r
-            "default_tool_flags"        : DefaultToolFlag,\r
-            "platform_tool_flags"       : [PlatformInfo.BuildOption[tool] for tool in PlatformInfo.ToolPath],\r
-            "module_tool_flags"         : [self.ModuleInfo.BuildOption[tool] for tool in PlatformInfo.ToolPath],\r
-\r
-            "tool_code"                 : PlatformInfo.ToolPath.keys(),\r
-            "tool_path"                 : PlatformInfo.ToolPath.values(),\r
-\r
-            "shell_command_code"        : gShellCommand[MakeType].keys(),\r
-            "shell_command"             : gShellCommand[MakeType].values(),\r
+            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),\r
+            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),\r
 \r
             "module_entry_point"        : EntryPoint,\r
-            "include_path_prefix"       : gIncludeFlag[PlatformInfo.ToolChainFamily["CC"]],\r
-            "dlink_output_flag"         : PlatformInfo.OutputFlag["DLINK"],\r
-            "slink_output_flag"         : PlatformInfo.OutputFlag["SLINK"],\r
-            "start_group_flag"          : gStartGroupFlag[PlatformInfo.ToolChainFamily["DLINK"]],\r
-            "end_group_flag"            : gEndGroupFlag[PlatformInfo.ToolChainFamily["DLINK"]],\r
-            "include_path"              : self.ModuleInfo.IncludePathList,\r
-            #"target_file"               : self.TargetFileList,\r
-            #"object_file"               : self.ObjectFileList,\r
+            "include_path_prefix"       : self._INC_FLAG_[self.PlatformInfo.ToolChainFamily["CC"]],\r
+            "dlink_output_flag"         : self.PlatformInfo.OutputFlag["DLINK"],\r
+            "slink_output_flag"         : self.PlatformInfo.OutputFlag["SLINK"],\r
+            "start_group_flag"          : self._LIB_GROUP_START_[self.PlatformInfo.ToolChainFamily["DLINK"]],\r
+            "end_group_flag"            : self._LIB_GROUP_END[self.PlatformInfo.ToolChainFamily["DLINK"]],\r
+            "include_path"              : self._AutoGenObject.IncludePathList,\r
             "library_file"              : self.LibraryFileList,\r
             "remaining_build_target"    : self.ResultFileList,\r
             "system_library"            : self.SystemLibraryList,\r
             "common_dependency_file"    : self.CommonFileDependency,\r
-            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList, MakeType),\r
-            "remove_directory_command"  : gRemoveDirectoryCommand[MakeType],\r
-            "remove_file_command"       : gRemoveFileCommand[MakeType],\r
-            "copy_file_command"         : gCopyFileCommand[MakeType],\r
-            "clean_command"             : self.GetRemoveDirectoryCommand(["$(OUTPUT_DIR)"], MakeType),\r
-            "cleanall_command"          : self.GetRemoveDirectoryCommand(["$(DEBUG_DIR)", "$(OUTPUT_DIR)"], MakeType),\r
+            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
+            "clean_command"             : self.GetRemoveDirectoryCommand(["$(OUTPUT_DIR)"]),\r
+            "cleanall_command"          : self.GetRemoveDirectoryCommand(["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]),\r
             "dependent_library_build_directory" : self.LibraryBuildDirectoryList,\r
-            "build_type"                        : self.BuildType,\r
             "source_file_macro"         : SourceFileMacroList,\r
             "target_file_macro"         : TargetFileMacroList,\r
             "source_file_macro_name"    : SourceFileMacroNameList,\r
@@ -887,94 +515,7 @@ class Makefile(object):
             "copy_autogen_h"            : CopyAutoGenHeaderFile,\r
         }\r
 \r
-        self.PrepareDirectory()\r
-\r
-        AutoGenMakefile = TemplateString()\r
-        AutoGenMakefile.Append(gModuleMakefileTemplate, MakefileTemplateDict)\r
-\r
-        FilePath = ""\r
-        if File == None:\r
-            os.chdir(self.ModuleInfo.PlatformInfo.BuildDir)\r
-            os.chdir(self.ModuleInfo.MakeFileDir)\r
-            FilePath = MakefileName\r
-        else:\r
-            FilePath = File\r
-\r
-        Result = SaveFileOnChange(FilePath, str(AutoGenMakefile))\r
-        os.chdir(self.ModuleInfo.WorkspaceDir)\r
-        return Result\r
-\r
-    ## Create customized makefile for a module\r
-    #\r
-    #   @param      File        The path of the makefile\r
-    #   @param      MakeType    GNU makefile or MS makefile\r
-    #\r
-    #   @retval     True        If the file is changed or doesn't exist\r
-    #   @retval     False       If the file exists and its content is not changed\r
-    #                           since last time\r
-    #\r
-    def GenerateCustomBuildMakefile(self, File=None, MakeType=gMakeType):\r
-        if MakeType not in gDirectorySeparator:\r
-            EdkLogger.error("GenMake", PARAMETER_INVALID, "Invalid Makefile type", ExtraData=MakeType)\r
-        Separator = gDirectorySeparator[MakeType]\r
-\r
-        try:\r
-            CustomMakefile = open(os.path.join(self.ModuleInfo.WorkspaceDir, self .ModuleInfo.CustomMakefile[MakeType]), 'r').read()\r
-        except:\r
-            EdkLogger.error(None, FILE_OPEN_FAILURE, ExtraData=self .ModuleInfo.CustomMakefile[MakeType])\r
-\r
-        MakefileName = gMakefileName[MakeType]\r
-        MakefileTemplateDict = {\r
-            "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),\r
-            "makefile_header"           : gMakefileHeader % MakefileName,\r
-            "platform_name"             : self.PlatformInfo.Name,\r
-            "platform_guid"             : self.PlatformInfo.Guid,\r
-            "platform_version"          : self.PlatformInfo.Version,\r
-            "platform_relative_directory": self.PlatformInfo.SourceDir,\r
-            "platform_output_directory" : self.PlatformInfo.OutputDir,\r
-\r
-            "module_name"               : self.ModuleInfo.Name,\r
-            "module_guid"               : self.ModuleInfo.Guid,\r
-            "module_version"            : self.ModuleInfo.Version,\r
-            "module_type"               : self.ModuleInfo.ModuleType,\r
-            "module_file_base_name"     : self.ModuleInfo.FileBase,\r
-            "module_relative_directory" : self.ModuleInfo.SourceDir,\r
-\r
-            "architecture"              : self.ModuleInfo.Arch,\r
-            "toolchain_tag"             : self.ModuleInfo.ToolChain,\r
-            "build_target"              : self.ModuleInfo.BuildTarget,\r
-\r
-            "platform_build_directory"  : self.PlatformInfo.BuildDir,\r
-\r
-            "separator"                 : Separator,\r
-            "default_tool_flags"        : self.PlatformInfo.ToolOption.values(),\r
-            "platform_tool_flags"       : self.PlatformInfo.BuildOption.values(),\r
-            "module_tool_flags"         : self.ModuleInfo.BuildOption.values(),\r
-\r
-            "shell_command_code"        : gShellCommand[MakeType].keys(),\r
-            "shell_command"             : gShellCommand[MakeType].values(),\r
-\r
-            "tool_code"                 : self.PlatformInfo.ToolPath.keys(),\r
-            "tool_path"                 : self.PlatformInfo.ToolPath.values(),\r
-\r
-            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList, MakeType),\r
-            "directory_to_be_created"   : self.IntermediateDirectoryList,\r
-            "dependent_library_build_directory" : self.LibraryBuildDirectoryList,\r
-            "custom_makefile_content"   : CustomMakefile\r
-        }\r
-\r
-        self.PrepareDirectory()\r
-\r
-        AutoGenMakefile = TemplateString()\r
-        AutoGenMakefile.Append(gCustomMakefileTemplate, MakefileTemplateDict)\r
-\r
-        FilePath = ""\r
-        if File == None:\r
-            FilePath = path.join(self.ModuleInfo.WorkspaceDir, self.ModuleInfo.MakeFileDir, MakefileName)\r
-        else:\r
-            FilePath = File\r
-\r
-        return SaveFileOnChange(FilePath, str(AutoGenMakefile))\r
+        return MakefileTemplateDict\r
 \r
     ## Process source files to generate makefile targets and dependencies\r
     #\r
@@ -984,21 +525,21 @@ class Makefile(object):
     #\r
     #   @param      MakeType    GNU makefile or MS makefile\r
     #\r
-    def ProcessSourceFileList(self, MakeType=gMakeType):\r
-        Separator = gDirectorySeparator[MakeType]\r
+    def ProcessSourceFileList(self):\r
+        Separator = self._SEP_[self._FileType]\r
 \r
         ForceIncludedFile = []\r
         SourceFileList = []\r
 \r
         if "CC" not in self.PlatformInfo.ToolChainFamily:\r
             EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No CC tool found",\r
-                            ExtraData=str(self.ModuleInfo.Module))\r
+                            ExtraData=str(self._AutoGenObject.Module))\r
         Family = self.PlatformInfo.ToolChainFamily["CC"]\r
         BuildRule = self.PlatformInfo.BuildRule\r
 \r
         CCodeFlag = False\r
-        FileList = self.ModuleInfo.SourceFileList\r
-        SourceDir = os.path.join(self.ModuleInfo.WorkspaceDir, self.ModuleInfo.SourceDir)\r
+        FileList = self._AutoGenObject.SourceFileList\r
+        SourceDir = os.path.join(self._AutoGenObject.WorkspaceDir, self._AutoGenObject.SourceDir)\r
         for FileInfo in FileList:\r
             F, SrcFileType, SrcFileBuildRule = FileInfo\r
             # no rule, no build\r
@@ -1104,7 +645,7 @@ class Makefile(object):
 \r
         # Build AutoGen files only if we have C source files\r
         if CCodeFlag == True:\r
-            for F in self.ModuleInfo.AutoGenFileList:\r
+            for F in self._AutoGenObject.AutoGenFileList:\r
                 SrcFileName = path.basename(F)\r
                 SrcFileBase, SrcFileExt = path.splitext(SrcFileName)\r
                 SrcFileDir = path.dirname(F)\r
@@ -1115,7 +656,7 @@ class Makefile(object):
                     if P not in self.IntermediateDirectoryList:\r
                         self.IntermediateDirectoryList.append(P)\r
 \r
-                SrcFileRelativePath = os.path.join(self.ModuleInfo.DebugDir, F)\r
+                SrcFileRelativePath = os.path.join(self._AutoGenObject.DebugDir, F)\r
 \r
                 SrcFileType, SrcFileBuildRule = BuildRule.Get(SrcFileExt, Family)\r
                 if SrcFileType != None and SrcFileType == "C-Header-File":\r
@@ -1123,7 +664,7 @@ class Makefile(object):
                 if SrcFileBuildRule == None or SrcFileBuildRule.CommandList == []:\r
                     continue\r
 \r
-                SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(F, self.ModuleInfo.DebugDir, Separator)\r
+                SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(F, self._AutoGenObject.DebugDir, Separator)\r
 \r
                 if SrcFileType not in self.SourceFileDatabase:\r
                     self.SourceFileDatabase[SrcFileType] = []\r
@@ -1164,7 +705,7 @@ class Makefile(object):
         #\r
         # Search dependency file list for each source file\r
         #\r
-        self.FileDependency = self.GetFileDependency(SourceFileList, ForceIncludedFile, self.ModuleInfo.IncludePathList)\r
+        self.FileDependency = self.GetFileDependency(SourceFileList, ForceIncludedFile, self._AutoGenObject.IncludePathList)\r
         DepSet = None\r
         for File in self.FileDependency:\r
             # skip non-C files\r
@@ -1201,11 +742,11 @@ class Makefile(object):
     ## Process binary files to generate makefile targets and dependencies\r
     #\r
     # All binary files are just copied to $(OUTPUT_DIR)\r
-    #\r
+    # \r
     #   @param      MakeType    GNU makefile or MS makefile\r
     #\r
-    def ProcessBinaryFileList(self, MakeType=gMakeType):\r
-        BinaryFiles = self.ModuleInfo.BinaryFileDict\r
+    def ProcessBinaryFileList(self):\r
+        BinaryFiles = self._AutoGenObject.BinaryFileDict\r
         BuildTargetString = "%(dst)s : %(src)s\n"\\r
                             "\t$(CP) %(src)s %(dst)s\n"\r
         for FileType in BinaryFiles:\r
@@ -1223,17 +764,10 @@ class Makefile(object):
     #\r
     #   @param      MakeType    GNU makefile or MS makefile\r
     #\r
-    def ProcessDependentLibrary(self, MakeType=gMakeType):\r
-        for LibraryModule in self.ModuleInfo.DependentLibraryList:\r
-            LibraryFile = str(LibraryModule)\r
-            FileBase = path.basename(LibraryFile).split(".")[0]\r
-            LibraryBuildPath = path.dirname(LibraryFile) + gDirectorySeparator[MakeType] + FileBase\r
-            self.LibraryBuildDirectoryList.append(LibraryBuildPath)\r
-            self.LibraryFileList.append(gDirectorySeparator[MakeType].join([LibraryBuildPath, "OUTPUT", LibraryModule.BaseName + ".lib"]))\r
-\r
-    ## Determine the root directory for a platform build\r
-    def GetPlatformBuildDirectory(self):\r
-        return self.PlatformInfo.BuildDir\r
+    def ProcessDependentLibrary(self):\r
+        for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
+            self.LibraryBuildDirectoryList.append(LibraryAutoGen.BuildDir)\r
+            self.LibraryFileList.append(os.path.join(LibraryAutoGen.OutputDir, LibraryAutoGen.Name + ".lib"))\r
 \r
     ## Return a list containing source file's dependencies\r
     #\r
@@ -1248,7 +782,7 @@ class Makefile(object):
         for F in FileList:\r
             Dependency[F] = self.GetDependencyList(F, ForceInculeList, SearchPathList)\r
         return Dependency\r
-\r
+    \r
     ## Find dependencies for one source file\r
     #\r
     #  By searching recursively "#include" directive in file, find out all the\r
@@ -1267,14 +801,14 @@ class Makefile(object):
         FileStack = [File] + ForceList\r
         DependencySet = set()\r
         MacroUsedByIncludedFile = False\r
-\r
-        if self.ModuleInfo.Arch not in gDependencyDatabase:\r
-            gDependencyDatabase[self.ModuleInfo.Arch] = {}\r
-        DepDb = gDependencyDatabase[self.ModuleInfo.Arch]\r
+    \r
+        if self._AutoGenObject.Arch not in gDependencyDatabase:\r
+            gDependencyDatabase[self._AutoGenObject.Arch] = {}\r
+        DepDb = gDependencyDatabase[self._AutoGenObject.Arch]\r
         while len(FileStack) > 0:\r
             EdkLogger.debug(EdkLogger.DEBUG_0, "Stack %s" % "\n\t".join(FileStack))\r
             F = FileStack.pop()\r
-\r
+    \r
             CurrentFileDependencyList = []\r
             if F in DepDb and not IsChanged(F):\r
                 CurrentFileDependencyList = DepDb[F]\r
@@ -1286,16 +820,16 @@ class Makefile(object):
                     Fd = open(F, 'r')\r
                 except:\r
                     EdkLogger.error("AutoGen", FILE_OPEN_FAILURE, ExtraData=F)\r
-\r
+    \r
                 FileContent = Fd.read()\r
                 Fd.close()\r
                 if len(FileContent) == 0:\r
                     continue\r
-\r
+    \r
                 if FileContent[0] == 0xff or FileContent[0] == 0xfe:\r
                     FileContent = unicode(FileContent, "utf-16")\r
                 IncludedFileList = gIncludePattern.findall(FileContent)\r
-\r
+    \r
                 CurrentFilePath = os.path.dirname(F)\r
                 for Inc in IncludedFileList:\r
                     # if there's macro used to reference header file, expand it\r
@@ -1320,7 +854,7 @@ class Makefile(object):
                         break\r
                     else:\r
                         EdkLogger.verbose("%s included by %s was not found in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList)))\r
-\r
+    \r
                 if not MacroUsedByIncludedFile:\r
                     if F == File:\r
                         CurrentFileDependencyList += ForceList\r
@@ -1330,7 +864,7 @@ class Makefile(object):
                     #\r
                     DepDb[F] = CurrentFileDependencyList\r
             DependencySet.update(CurrentFileDependencyList)\r
-\r
+    \r
         #\r
         # If there's macro used in included file, always build the file by\r
         # returning a empty dependency\r
@@ -1340,50 +874,535 @@ class Makefile(object):
         else:\r
             DependencyList = list(DependencySet)  # remove duplicate ones\r
             DependencyList.append(File)\r
+    \r
+        return DependencyList        \r
 \r
-        return DependencyList\r
+    _TemplateDict = property(_CreateTemplateDict)\r
 \r
-    ## Get the root directory list for intermediate files of all modules build\r
-    #\r
-    #   @retval     list    The list of directory\r
-    #\r
-    def GetModuleBuildDirectoryList(self):\r
-        DirList = []\r
-        for Arch in self.PlatformInfo:\r
-            for ModuleAutoGen in self.PlatformInfo[Arch].ModuleAutoGenList:\r
-                DirList.append(ModuleAutoGen.BuildInfo.BuildDir)\r
-        return DirList\r
+class CustomMakefile(BuildFile):\r
+    _TEMPLATE_ = '''\\r
+${makefile_header}\r
 \r
-    ## Get the root directory list for intermediate files of all libraries build\r
-    #\r
-    #   @retval     list    The list of directory\r
+#\r
+# Platform Macro Definition\r
+#\r
+PLATFORM_NAME = ${platform_name}\r
+PLATFORM_GUID = ${platform_guid}\r
+PLATFORM_VERSION = ${platform_version}\r
+PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
+PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
+PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
+\r
+#\r
+# Module Macro Definition\r
+#\r
+MODULE_NAME = ${module_name}\r
+MODULE_GUID = ${module_guid}\r
+MODULE_VERSION = ${module_version}\r
+MODULE_TYPE = ${module_type}\r
+MODULE_FILE_BASE_NAME = ${module_file_base_name}\r
+BASE_NAME = $(MODULE_NAME)\r
+MODULE_RELATIVE_DIR = ${module_relative_directory}\r
+MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}\r
+\r
+#\r
+# Build Configuration Macro Definition\r
+#\r
+ARCH = ${architecture}\r
+TOOLCHAIN_TAG = ${toolchain_tag}\r
+TARGET = ${build_target}\r
+\r
+#\r
+# Build Directory Macro Definition\r
+#\r
+# PLATFORM_BUILD_DIR = ${platform_build_directory}\r
+BUILD_DIR = ${platform_build_directory}\r
+BIN_DIR = $(BUILD_DIR)${separator}${architecture}\r
+LIB_DIR = $(BIN_DIR)\r
+MODULE_BUILD_DIR = $(BUILD_DIR)${separator}${architecture}${separator}${module_relative_directory}${separator}${module_file_base_name}\r
+OUTPUT_DIR = $(MODULE_BUILD_DIR)${separator}OUTPUT\r
+DEBUG_DIR = $(MODULE_BUILD_DIR)${separator}DEBUG\r
+DEST_DIR_OUTPUT = $(OUTPUT_DIR)\r
+DEST_DIR_DEBUG = $(DEBUG_DIR)\r
+\r
+#\r
+# Tools Flag Macro (from platform/module description file, tools_def.txt)\r
+#\r
+${BEGIN}${tool_code}_FLAGS = ${module_tool_flags}\r
+${END}\r
+\r
+#\r
+# Tools Path Macro\r
+#\r
+${BEGIN}${tool_code} = ${tool_path}\r
+${END}\r
+\r
+MAKE_FILE = ${makefile_path}\r
+\r
+#\r
+# Shell Command Macro\r
+#\r
+${BEGIN}${shell_command_code} = ${shell_command}\r
+${END}\r
+\r
+${custom_makefile_content}\r
+\r
+#\r
+# Target used when called from platform makefile, which will bypass the build of dependent libraries\r
+#\r
+\r
+pbuild: init all\r
+\r
+\r
+#\r
+# ModuleTarget\r
+#\r
+\r
+mbuild: init all\r
+\r
+\r
+#\r
+# Initialization target: print build information and create necessary directories\r
+#\r
+init:\r
+\t-@echo Building ... $(MODULE_NAME) [$(ARCH)]\r
+${BEGIN}\t-@${create_directory_command}\n${END}\\r
+\r
+'''\r
+    def __init__(self, ModuleAutoGen):\r
+        BuildFile.__init__(self, ModuleAutoGen)\r
+        self.PlatformInfo = self._AutoGenObject.PlatformInfo\r
+        self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]\r
+\r
+    ## Create customized makefile for a module\r
+    #\r
+    #   @param      File        The path of the makefile\r
+    #   @param      MakeType    GNU makefile or MS makefile\r
+    #\r
+    #   @retval     True        If the file is changed or doesn't exist\r
+    #   @retval     False       If the file exists and its content is not changed\r
+    #                           since last time\r
+    #\r
+    def _CreateTemplateDict(self):\r
+        Separator = self._SEP_[self._FileType]\r
+        try:\r
+            CustomMakefile = open(\r
+                                os.path.join(\r
+                                            self._AutoGenObject.WorkspaceDir, \r
+                                            self._AutoGenObject.CustomMakefile[self._FileType]\r
+                                            ),\r
+                                'r').read()\r
+        except:\r
+            EdkLogger.error('build', FILE_OPEN_FAILURE, ExtraData=self._AutoGenObject.CustomMakefile[self._FileType])\r
+\r
+        MakefileName = self._FILE_NAME_[self._FileType]\r
+        MakefileTemplateDict = {\r
+            "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
+            "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),\r
+            "platform_name"             : self.PlatformInfo.Name,\r
+            "platform_guid"             : self.PlatformInfo.Guid,\r
+            "platform_version"          : self.PlatformInfo.Version,\r
+            "platform_relative_directory": self.PlatformInfo.SourceDir,\r
+            "platform_output_directory" : self.PlatformInfo.OutputDir,\r
+\r
+            "module_name"               : self._AutoGenObject.Name,\r
+            "module_guid"               : self._AutoGenObject.Guid,\r
+            "module_version"            : self._AutoGenObject.Version,\r
+            "module_type"               : self._AutoGenObject.ModuleType,\r
+            "module_file_base_name"     : self._AutoGenObject.FileBase,\r
+            "module_relative_directory" : self._AutoGenObject.SourceDir,\r
+\r
+            "architecture"              : self._AutoGenObject.Arch,\r
+            "toolchain_tag"             : self._AutoGenObject.ToolChain,\r
+            "build_target"              : self._AutoGenObject.BuildTarget,\r
+\r
+            "platform_build_directory"  : self.PlatformInfo.BuildDir,\r
+\r
+            "separator"                 : Separator,\r
+            "module_tool_flags"         : [self._AutoGenObject.BuildOption[tool] for tool in self.PlatformInfo.ToolPath],\r
+\r
+            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),\r
+            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),\r
+\r
+            "tool_code"                 : self.PlatformInfo.ToolPath.keys(),\r
+            "tool_path"                 : self.PlatformInfo.ToolPath.values(),\r
+\r
+            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
+            "custom_makefile_content"   : CustomMakefile\r
+        }\r
+\r
+        return MakefileTemplateDict\r
+\r
+    _TemplateDict = property(_CreateTemplateDict)\r
+\r
+class PlatformMakefile(BuildFile):\r
+    _TEMPLATE_ = '''\\r
+${makefile_header}\r
+\r
+#\r
+# Platform Macro Definition\r
+#\r
+PLATFORM_NAME = ${platform_name}\r
+PLATFORM_GUID = ${platform_guid}\r
+PLATFORM_VERSION = ${platform_version}\r
+PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
+PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
+\r
+#\r
+# Build Configuration Macro Definition\r
+#\r
+TOOLCHAIN_TAG = ${toolchain_tag}\r
+TARGET = ${build_target}\r
+\r
+#\r
+# Build Directory Macro Definition\r
+#\r
+BUILD_DIR = ${platform_build_directory}\r
+FV_DIR = ${platform_build_directory}${separator}FV\r
+\r
+#\r
+# Shell Command Macro\r
+#\r
+${BEGIN}${shell_command_code} = ${shell_command}\r
+${END}\r
+\r
+MAKE = ${make_path}\r
+MAKE_FLAGS = ${make_flag}\r
+MAKE_FILE = ${makefile_path}\r
+\r
+#\r
+# Default target\r
+#\r
+all: init build_libraries build_modules\r
+\r
+#\r
+# Initialization target: print build information and create necessary directories\r
+#\r
+init:\r
+\t-@echo Building ... $(PLATFORM_NAME) [${build_architecture_list}]\r
+\t${BEGIN}-@${create_directory_command}\r
+\t${END}\r
+#\r
+# library build target\r
+#\r
+libraries: init build_libraries\r
+\r
+#\r
+# module build target\r
+#\r
+modules: init build_libraries build_modules\r
+\r
+#\r
+# Build all libraries:\r
+#\r
+build_libraries:\r
+${BEGIN}\t@cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) pbuild\r
+${END}\t@cd $(BUILD_DIR)\r
+\r
+#\r
+# Build all modules:\r
+#\r
+build_modules:\r
+${BEGIN}\t@cd ${module_build_directory} && "$(MAKE)" $(MAKE_FLAGS) pbuild\r
+${END}\t@cd $(BUILD_DIR)\r
+\r
+#\r
+# Clean intermediate files\r
+#\r
+clean:\r
+\t${BEGIN}@cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) clean\r
+\t${END}${BEGIN}@cd ${module_build_directory} && "$(MAKE)" $(MAKE_FLAGS) clean\r
+\t${END}@cd $(BUILD_DIR)\r
+\r
+#\r
+# Clean all generated files except to makefile\r
+#\r
+cleanall:\r
+${BEGIN}\t${cleanall_command}\r
+${END}\r
+\r
+#\r
+# Clean all library files\r
+#\r
+cleanlib:\r
+\t${BEGIN}@cd ${library_build_directory} && "$(MAKE)" $(MAKE_FLAGS) cleanall\r
+\t${END}@cd $(BUILD_DIR)\n\r
+'''\r
+\r
+    def __init__(self, PlatformAutoGen):\r
+        BuildFile.__init__(self, PlatformAutoGen)\r
+        self.ModuleBuildCommandList = []\r
+        self.ModuleMakefileList = []\r
+        self.IntermediateDirectoryList = []\r
+        self.ModuleBuildDirectoryList = []\r
+        self.LibraryBuildDirectoryList = []\r
+\r
+    ## Create makefile of platform\r
+    #\r
+    #   @param      File        The path of the makefile\r
+    #   @param      MakeType    GNU makefile or MS makefile\r
+    #\r
+    #   @retval     True        If the file is changed or doesn't exist\r
+    #   @retval     False       If the file exists and its content is not changed\r
+    #                           since last time\r
+    #\r
+    def _CreateTemplateDict(self):\r
+        Separator = self._SEP_[self._FileType]\r
+\r
+        PlatformInfo = self._AutoGenObject\r
+        if "MAKE" not in PlatformInfo.ToolPath:\r
+            EdkLogger.error("GenMake", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!")\r
+\r
+        self.IntermediateDirectoryList = ["$(BUILD_DIR)"]\r
+        self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()\r
+        self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()\r
+\r
+        MakefileName = self._FILE_NAME_[self._FileType]\r
+        MakefileTemplateDict = {\r
+            "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
+            "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),\r
+            "platform_name"             : PlatformInfo.Name,\r
+            "platform_guid"             : PlatformInfo.Guid,\r
+            "platform_version"          : PlatformInfo.Version,\r
+            "platform_relative_directory": PlatformInfo.SourceDir,\r
+            "platform_output_directory" : PlatformInfo.OutputDir,\r
+            "platform_build_directory"  : PlatformInfo.BuildDir,\r
+\r
+            "toolchain_tag"             : PlatformInfo.ToolChain,\r
+            "build_target"              : PlatformInfo.BuildTarget,\r
+            "make_path"                 : PlatformInfo.ToolPath["MAKE"],\r
+            "make_flag"                 : PlatformInfo.ToolOption["MAKE"],\r
+            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),\r
+            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),\r
+            "build_architecture_list"   : self._AutoGenObject.Arch,\r
+            "architecture"              : self._AutoGenObject.Arch,\r
+            "separator"                 : Separator,\r
+            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
+            "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),\r
+            "library_build_directory"   : self.LibraryBuildDirectoryList,\r
+            "module_build_directory"    : self.ModuleBuildDirectoryList,\r
+            "active_platform"           : PlatformInfo.WorkspaceDir + Separator + str(PlatformInfo),\r
+        }\r
+\r
+        return MakefileTemplateDict\r
+\r
+    ## Get the root directory list for intermediate files of all modules build\r
+    #\r
+    #   @retval     list    The list of directory\r
+    #\r
+    def GetModuleBuildDirectoryList(self):\r
+        DirList = []\r
+        for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:\r
+            DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))\r
+        return DirList\r
+\r
+    ## Get the root directory list for intermediate files of all libraries build\r
+    #\r
+    #   @retval     list    The list of directory\r
     #\r
     def GetLibraryBuildDirectoryList(self):\r
         DirList = []\r
-        for Arch in self.PlatformInfo:\r
-            for LibraryAutoGen in self.PlatformInfo[Arch].LibraryAutoGenList:\r
-                DirList.append(LibraryAutoGen.BuildInfo.BuildDir)\r
+        for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
+            DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))\r
         return DirList\r
 \r
-    ## Return a list of directory creation command string\r
+    _TemplateDict = property(_CreateTemplateDict)\r
+\r
+class TopLevelMakefile(BuildFile):\r
+    _TEMPLATE_ = '''\\r
+${makefile_header}\r
+\r
+#\r
+# Platform Macro Definition\r
+#\r
+PLATFORM_NAME = ${platform_name}\r
+PLATFORM_GUID = ${platform_guid}\r
+PLATFORM_VERSION = ${platform_version}\r
+\r
+#\r
+# Build Configuration Macro Definition\r
+#\r
+TOOLCHAIN_TAG = ${toolchain_tag}\r
+TARGET = ${build_target}\r
+\r
+#\r
+# Build Directory Macro Definition\r
+#\r
+BUILD_DIR = ${platform_build_directory}\r
+FV_DIR = ${platform_build_directory}${separator}FV\r
+\r
+#\r
+# Shell Command Macro\r
+#\r
+${BEGIN}${shell_command_code} = ${shell_command}\r
+${END}\r
+\r
+MAKE = ${make_path}\r
+MAKE_FLAGS = ${make_flag}\r
+MAKE_FILE = ${makefile_path}\r
+\r
+#\r
+# Default target\r
+#\r
+all: modules fds\r
+\r
+#\r
+# Initialization target: print build information and create necessary directories\r
+#\r
+init:\r
+\t-@echo Building ... $(PLATFORM_NAME) [${build_architecture_list}]\r
+\t${BEGIN}-@${create_directory_command}\r
+\t${END}\r
+#\r
+# library build target\r
+#\r
+libraries: init\r
+${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) libraries\r
+${END}\t@cd $(BUILD_DIR)\r
+\r
+#\r
+# module build target\r
+#\r
+modules: init\r
+${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) modules\r
+${END}\t@cd $(BUILD_DIR)\r
+\r
+#\r
+# Flash Device Image Target\r
+#\r
+fds: init\r
+\t-@cd $(FV_DIR)\r
+${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN_TAG) -b $(TARGET) -p ${active_platform} -a ${build_architecture_list} ${log_level}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -y ${macro} ${END}\r
+\r
+#\r
+# run command for emulator platform only\r
+#\r
+run:\r
+\tcd $(BUILD_DIR)${separator}IA32\r
+\tSecMain\r
+\tcd $(BUILD_DIR)\r
+\r
+#\r
+# Clean intermediate files\r
+#\r
+clean:\r
+${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) clean\r
+${END}\t@cd $(BUILD_DIR)\r
+\r
+#\r
+# Clean all generated files except to makefile\r
+#\r
+cleanall:\r
+${BEGIN}\t${cleanall_command}\r
+${END}\r
+\r
+#\r
+# Clean all library files\r
+#\r
+cleanlib:\r
+${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) cleanlib\r
+${END}\t@cd $(BUILD_DIR)\n\r
+'''\r
+\r
+    def __init__(self, Workspace):\r
+        BuildFile.__init__(self, Workspace)\r
+        self.IntermediateDirectoryList = []\r
+\r
+    ## Create makefile of platform\r
     #\r
-    #   @param      DirList     The list of directory to be created\r
+    #   @param      File        The path of the makefile\r
     #   @param      MakeType    GNU makefile or MS makefile\r
     #\r
-    #   @retval     list        The directory creation command list\r
+    #   @retval     True        If the file is changed or doesn't exist\r
+    #   @retval     False       If the file exists and its content is not changed\r
+    #                           since last time\r
     #\r
-    def GetCreateDirectoryCommand(self, DirList, MakeType=gMakeType):\r
-        return [gCreateDirectoryCommandTemplate[MakeType] % {'dir':Dir} for Dir in DirList]\r
+    def _CreateTemplateDict(self):\r
+        Separator = self._SEP_[self._FileType]\r
 \r
-    ## Return a list of directory removal command string\r
+        # any platform autogen object is ok because we just need common information\r
+        PlatformInfo = self._AutoGenObject\r
+\r
+        if "MAKE" not in PlatformInfo.ToolPath:\r
+            EdkLogger.error("GenMake", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!")\r
+\r
+        for Arch in PlatformInfo.ArchList:\r
+            self.IntermediateDirectoryList.append(Separator.join(["$(BUILD_DIR)", Arch]))\r
+        self.IntermediateDirectoryList.append("$(FV_DIR)")\r
+\r
+        # TRICK: for not generating GenFds call in makefile if no FDF file\r
+        MacroList = []\r
+        if PlatformInfo.FdfFile != None and PlatformInfo.FdfFile != "":\r
+            FdfFileList = [PlatformInfo.FdfFile]\r
+            # macros passed to GenFds\r
+            for MacroName in GlobalData.gGlobalDefines:\r
+                MacroList.append('"%s=%s"' % (MacroName, GlobalData.gGlobalDefines[MacroName]))    \r
+        else:\r
+            FdfFileList = []\r
+\r
+        # pass log level to external program called in makefile, currently GenFds.exe\r
+        LogLevel = EdkLogger.GetLevel()\r
+        if LogLevel == EdkLogger.VERBOSE:\r
+            LogOption = "-v"\r
+        elif LogLevel <= EdkLogger.DEBUG_9:\r
+            LogOption = "-d %d" % (LogLevel - 1)\r
+        elif LogLevel == EdkLogger.QUIET:\r
+            LogOption = "-q"\r
+        else:\r
+            LogOption = ""\r
+\r
+        MakefileName = self._FILE_NAME_[self._FileType]\r
+        MakefileTemplateDict = {\r
+            "makefile_header"           : self._FILE_HEADER_[self._FileType],\r
+            "makefile_path"             : os.path.join("$(BUILD_DIR)", MakefileName),\r
+            "platform_name"             : PlatformInfo.Name,\r
+            "platform_guid"             : PlatformInfo.Guid,\r
+            "platform_version"          : PlatformInfo.Version,\r
+            "platform_build_directory"  : PlatformInfo.BuildDir,\r
+\r
+            "toolchain_tag"             : PlatformInfo.ToolChain,\r
+            "build_target"              : PlatformInfo.BuildTarget,\r
+            "make_path"                 : PlatformInfo.ToolPath["MAKE"],\r
+            "make_flag"                 : PlatformInfo.ToolOption["MAKE"],\r
+            "shell_command_code"        : self._SHELL_CMD_[self._FileType].keys(),\r
+            "shell_command"             : self._SHELL_CMD_[self._FileType].values(),\r
+            'arch'                      : list(PlatformInfo.ArchList),\r
+            "build_architecture_list"   : ','.join(PlatformInfo.ArchList),\r
+            "separator"                 : Separator,\r
+            "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),\r
+            "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList),\r
+            "fdf_file"                  : FdfFileList,\r
+            "active_platform"           : PlatformInfo.WorkspaceDir + Separator + str(PlatformInfo),\r
+            "fd"                        : PlatformInfo.FdTargetList,\r
+            "fv"                        : PlatformInfo.FvTargetList,\r
+            "log_level"                 : LogOption,\r
+            "macro"                     : MacroList,\r
+        }\r
+\r
+        return MakefileTemplateDict\r
+\r
+    ## Get the root directory list for intermediate files of all modules build\r
     #\r
-    #   @param      DirList     The list of directory to be removed\r
-    #   @param      MakeType    GNU makefile or MS makefile\r
+    #   @retval     list    The list of directory\r
     #\r
-    #   @retval     list        The directory removal command list\r
+    def GetModuleBuildDirectoryList(self):\r
+        DirList = []\r
+        for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:\r
+            DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))\r
+        return DirList\r
+\r
+    ## Get the root directory list for intermediate files of all libraries build\r
+    #\r
+    #   @retval     list    The list of directory\r
     #\r
-    def GetRemoveDirectoryCommand(self, DirList, MakeType=gMakeType):\r
-        return [gRemoveDirectoryCommandTemplate[MakeType] % {'dir':Dir} for Dir in DirList]\r
+    def GetLibraryBuildDirectoryList(self):\r
+        DirList = []\r
+        for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
+            DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))\r
+        return DirList\r
+\r
+    _TemplateDict = property(_CreateTemplateDict)\r
+\r
 \r
 # This acts like the main() function for the script, unless it is 'import'ed into another script.\r
 if __name__ == '__main__':\r
index 03fe862..f8315c6 100644 (file)
@@ -346,7 +346,6 @@ TAB_ELSE_IF = '!elseif'
 TAB_ELSE = '!else'\r
 TAB_IF_DEF = '!ifdef'\r
 TAB_IF_N_DEF = '!ifndef'\r
-TAB_IF_EXIST = '!if exist'\r
 \r
 #\r
 # Unknown section\r
@@ -360,3 +359,7 @@ DATABASE_PATH = ":memory:" #"BuildDatabase.db"
 \r
 # used by ECC\r
 MODIFIER_LIST = ['IN', 'OUT', 'OPTIONAL', 'UNALIGNED', 'EFI_RUNTIMESERVICE', 'EFI_BOOTSERVICE', 'EFIAPI']\r
+\r
+# Dependency Expression\r
+DEPEX_SUPPORTED_OPCODE = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "END", "SOR", "TRUE", "FALSE", '(', ')']\r
+\r
index b91c15f..0c7442c 100755 (executable)
@@ -245,6 +245,41 @@ def DataRestore(File):
             Fd.close()\r
     return Data\r
 \r
+## Check if gvien file exists or not\r
+# \r
+#   @param      File    File name or path to be checked\r
+#   @param      Dir     The directory the file is relative to\r
+# \r
+#   @retval     True    if file exists\r
+#   @retval     False   if file doesn't exists\r
+# \r
+def ValidFile(File, Dir='.'):\r
+    Wd = os.getcwd()\r
+    os.chdir(Dir)\r
+    if not os.path.exists(File):\r
+        os.chdir(Wd)\r
+        return False\r
+    os.chdir(Wd)\r
+    return True\r
+\r
+## Get GUID value from given packages\r
+# \r
+#   @param      CName           The CName of the GUID\r
+#   @param      PackageList     List of packages looking-up in\r
+# \r
+#   @retval     GuidValue   if the CName is found in any given package\r
+#   @retval     None        if the CName is not found in all given packages\r
+# \r
+def GuidValue(CName, PackageList):\r
+    for P in PackageList:\r
+        if CName in P.Guids:\r
+            return P.Guids[CName]\r
+        if CName in P.Protocols:\r
+            return P.Protocols[CName]\r
+        if CName in P.Ppis:\r
+            return P.Ppis[CName]\r
+    return None\r
+\r
 ## A string template class\r
 #\r
 #  This class implements a template for string replacement. A string template\r
@@ -486,6 +521,14 @@ class sdict(IterableUserDict):
         self.__delitem__(key)\r
         return key, value\r
 \r
+    def update(self, dict=None, **kwargs):\r
+        if dict != None:\r
+            for k, v in dict.items():\r
+                self[k] = v\r
+        if len(kwargs):\r
+            for k, v in kwargs.items():\r
+                self[k] = v\r
+\r
 ## Dictionary with restricted keys\r
 #\r
 class rdict(dict):\r
index d9bb5ed..203e2a2 100644 (file)
@@ -229,7 +229,8 @@ class PpiClass(GuidProtocolPpiCommonClass):
 # @var DefaultValue:       To store value for DefaultValue\r
 #\r
 class SkuInfoClass(object):\r
-    def __init__(self, SkuIdName = '', SkuId = '', VariableName = '', VariableGuid = '', VariableOffset = '', HiiDefaultValue = '', VpdOffset = '', DefaultValue = ''):\r
+    def __init__(self, SkuIdName = '', SkuId = '', VariableName = '', VariableGuid = '', VariableOffset = '', \r
+                 HiiDefaultValue = '', VpdOffset = '', DefaultValue = '', VariableGuidValue = ''):\r
         self.SkuIdName = SkuIdName\r
         self.SkuId = SkuId\r
         \r
@@ -238,6 +239,7 @@ class SkuInfoClass(object):
         #\r
         self.VariableName = VariableName\r
         self.VariableGuid = VariableGuid\r
+        self.VariableGuidValue = VariableGuidValue\r
         self.VariableOffset = VariableOffset\r
         self.HiiDefaultValue = HiiDefaultValue\r
         \r
index b8c4a01..7d0dda1 100644 (file)
@@ -28,6 +28,7 @@ MODEL_FILE_DEC = 1012
 MODEL_FILE_DSC = 1013\r
 MODEL_FILE_FDF = 1014\r
 MODEL_FILE_INC = 1015\r
+MODEL_FILE_CIF = 1016\r
 \r
 MODEL_IDENTIFIER_FILE_HEADER = 2001\r
 MODEL_IDENTIFIER_FUNCTION_HEADER = 2002\r
@@ -48,7 +49,6 @@ MODEL_IDENTIFIER_MACRO_PROGMA = 2016
 MODEL_IDENTIFIER_FUNCTION_CALLING = 2018\r
 MODEL_IDENTIFIER_TYPEDEF = 2017\r
 MODEL_IDENTIFIER_FUNCTION_DECLARATION = 2019\r
-MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION = 2020\r
 \r
 MODEL_EFI_PROTOCOL = 3001\r
 MODEL_EFI_PPI = 3002\r
@@ -118,7 +118,6 @@ MODEL_LIST = [('MODEL_UNKNOWN', MODEL_UNKNOWN),
               ('MODEL_IDENTIFIER_FUNCTION_CALLING', MODEL_IDENTIFIER_FUNCTION_CALLING),\r
               ('MODEL_IDENTIFIER_TYPEDEF', MODEL_IDENTIFIER_TYPEDEF),\r
               ('MODEL_IDENTIFIER_FUNCTION_DECLARATION', MODEL_IDENTIFIER_FUNCTION_DECLARATION),\r
-              ('MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION', MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION),\r
               ('MODEL_EFI_PROTOCOL', MODEL_EFI_PROTOCOL),\r
               ('MODEL_EFI_PPI', MODEL_EFI_PPI),\r
               ('MODEL_EFI_GUID', MODEL_EFI_GUID),\r
index a3778a8..e698c9b 100644 (file)
@@ -11,6 +11,7 @@
 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 #\r
 \r
+from Common.Misc import sdict\r
 \r
 ## PcdClassObject\r
 #\r
 # @var Phase:                To store value for Phase, default is "DXE"\r
 #\r
 class PcdClassObject(object):\r
-    def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, IsOverrided = False):\r
+    def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, GuidValue = None):\r
         self.TokenCName = Name\r
         self.TokenSpaceGuidCName = Guid\r
+        self.TokenSpaceGuidValue = GuidValue\r
         self.Type = Type\r
         self.DatumType = DatumType\r
         self.DefaultValue = Value\r
         self.TokenValue = Token\r
         self.MaxDatumSize = MaxDatumSize\r
         self.SkuInfoList = SkuInfoList\r
-        self.IsOverrided = IsOverrided\r
         self.Phase = "DXE"\r
 \r
     ## Convert the class to a string\r
index 1a29e24..2fe4c55 100644 (file)
@@ -25,7 +25,7 @@ from Common.String import *
 from Common.Misc import Blist\r
 \r
 class MetaFileParser(object):\r
-    _DataType = {}\r
+    DataType = {}\r
     def __init__(self, FilePath, FileType, Table, Macros={}, Owner=-1, From=-1):\r
         self._Table = Table\r
         self._FileType = FileType\r
@@ -49,6 +49,7 @@ class MetaFileParser(object):
         self._SubsectionName = ''\r
         self._LastItem = -1\r
         self._Enabled = 0\r
+        self._Finished = False\r
 \r
     def _Store(self, *Args):\r
         return self._Table.Insert(*Args)\r
@@ -57,8 +58,26 @@ class MetaFileParser(object):
         raise NotImplementedError \r
 \r
     def _Done(self):\r
+        self._Finished = True\r
         self._Table.SetEndFlag()\r
 \r
+    def _GetTable(self):\r
+        if not self._Finished:\r
+            self.Start()\r
+        return self._Table\r
+\r
+    def _GetFinished(self):\r
+        return self._Finished\r
+\r
+    def _SetFinished(self, Value):\r
+        self._Finished = Value\r
+\r
+    # DataType = [section_header_name, scope1(arch), scope2(platform,moduletype)]\r
+    def __getitem__(self, DataInfo):\r
+        if type(DataInfo) != type(()):\r
+            DataInfo = (DataInfo,)\r
+        return self.Table.Query(*DataInfo)\r
+\r
     def _CommonParser(self):\r
         TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
         self._ValueList[0:len(TokenList)] = TokenList\r
@@ -86,8 +105,8 @@ class MetaFileParser(object):
                 EdkLogger.error('Parser', FORMAT_INVALID, "Different section names in the same section",\r
                                 File=self._FilePath, Line=self._LineIndex+1, ExtraData=self._CurrentLine)\r
             self._SectionName = ItemList[0].upper()\r
-            if self._SectionName in self._DataType:\r
-                self._SectionType = self._DataType[self._SectionName]\r
+            if self._SectionName in self.DataType:\r
+                self._SectionType = self.DataType[self._SectionName]\r
             else:\r
                 self._SectionType = MODEL_UNKNOWN\r
             # S1 is always Arch\r
@@ -127,10 +146,13 @@ class MetaFileParser(object):
             self._Macros = {}\r
         self._Macros[TokenList[0]] = TokenList[1]\r
 \r
-    _SectionParser = {}\r
+    _SectionParser  = {}\r
+    Table           = property(_GetTable)\r
+    Finished        = property(_GetFinished, _SetFinished)\r
+\r
 \r
 class InfParser(MetaFileParser):\r
-    _DataType = {\r
+    DataType = {\r
         TAB_UNKNOWN.upper() : MODEL_UNKNOWN,\r
         TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER,\r
         TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,\r
@@ -252,10 +274,10 @@ class InfParser(MetaFileParser):
         MODEL_EFI_DEPEX                 :   _DepexParser,\r
         MODEL_EFI_BINARY_FILE           :   MetaFileParser._PathParser,\r
         MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,\r
-    }    \r
+    }\r
 \r
 class DscParser(MetaFileParser):\r
-    _DataType = {\r
+    DataType = {\r
         TAB_SKUIDS.upper()                          :   MODEL_EFI_SKU_ID,\r
         TAB_LIBRARIES.upper()                       :   MODEL_EFI_LIBRARY_INSTANCE,\r
         TAB_LIBRARY_CLASSES.upper()                 :   MODEL_EFI_LIBRARY_CLASS,\r
@@ -397,8 +419,8 @@ class DscParser(MetaFileParser):
             \r
     def _SubsectionHeaderParser(self):\r
         self._SubsectionName = self._CurrentLine[1:-1].upper()\r
-        if self._SubsectionName in self._DataType:\r
-            self._SubsectionType = self._DataType[self._SubsectionName]\r
+        if self._SubsectionName in self.DataType:\r
+            self._SubsectionType = self.DataType[self._SubsectionName]\r
         else:\r
             self._SubsectionType = MODEL_UNKNOWN\r
 \r
@@ -412,7 +434,7 @@ class DscParser(MetaFileParser):
                             ExtraData=self._CurrentLine)\r
         DirectiveName = self._ValueList[0].upper()\r
         self._LastItem = self._Store(\r
-            self._DataType[DirectiveName],\r
+            self.DataType[DirectiveName],\r
             self._ValueList[0],\r
             self._ValueList[1],\r
             self._ValueList[2],\r
@@ -548,7 +570,7 @@ class DscParser(MetaFileParser):
     }\r
 \r
 class DecParser(MetaFileParser):\r
-    _DataType = {\r
+    DataType = {\r
         TAB_DEC_DEFINES.upper()                     :   MODEL_META_DATA_HEADER,\r
         TAB_INCLUDES.upper()                        :   MODEL_EFI_INCLUDE,\r
         TAB_LIBRARY_CLASSES.upper()                 :   MODEL_EFI_LIBRARY_CLASS,\r
index 6e3d95d..d41f6e5 100644 (file)
@@ -84,13 +84,9 @@ class ModuleTable(Table):
     #\r
     # @retval:       A recordSet of all found records \r
     #\r
-    def Query(self, Model, Value1=None, Arch=None, Platform=None):\r
+    def Query(self, Model, Arch=None, Platform=None):\r
         ConditionString = "Model=%s AND Enabled>=0" % Model\r
-        if Value1 == None:\r
-            ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
-        else:\r
-            ValueString = "Value2,Value3,Scope1,Scope2,ID,StartLine"\r
-            ConditionString = "Value1='%s'" % Value1\r
+        ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
 \r
         if Arch != None and Arch != 'COMMON':\r
             ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch\r
@@ -164,13 +160,9 @@ class PackageTable(Table):
     #\r
     # @retval:       A recordSet of all found records \r
     #\r
-    def Query(self, Model, Value1=None, Arch=None):\r
+    def Query(self, Model, Arch=None):\r
         ConditionString = "Model=%s AND Enabled>=0" % Model\r
-        if Value1 == None:\r
-            ValueString = "Value1,Value2,Value3,Scope1,ID,StartLine"\r
-        else:\r
-            ValueString = "Value2,Value3,Scope1,ID,StartLine"\r
-            ConditionString = "Value1='%s'" % Value1\r
+        ValueString = "Value1,Value2,Value3,Scope1,ID,StartLine"\r
 \r
         if Arch != None and Arch != 'COMMON':\r
             ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch\r
@@ -244,13 +236,9 @@ class PlatformTable(Table):
     #\r
     # @retval:       A recordSet of all found records \r
     #\r
-    def Query(self, Model, Value1=None, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):\r
+    def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):\r
         ConditionString = "Model=%s AND Enabled>=0" % Model\r
-        if Value1 == None:\r
-            ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
-        else:\r
-            ValueString = "Value2,Value3,Scope1,Scope2,ID,StartLine"\r
-            ConditionString = "Value1='%s'" % Value1\r
+        ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
 \r
         if Scope1 != None and Scope1 != 'COMMON':\r
             ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Scope1\r
index 7fe35a0..70ce4fa 100644 (file)
@@ -23,49 +23,13 @@ from CommonDataClass.DataClass import *
 from CommonDataClass.ModuleClass import *\r
 from Common.String import *\r
 from Common.DataType import *\r
-from Common.Misc import tdict\r
-from Common.Misc import sdict\r
+from Common.Misc import *\r
 \r
 from MetaDataTable import *\r
 from MetaFileTable import *\r
 from MetaFileParser import *\r
 from BuildClassObject import *\r
 \r
-## Check if gvien file exists or not\r
-#\r
-#   @param      File    File name or path to be checked\r
-#   @param      Dir     The directory the file is relative to\r
-#\r
-#   @retval     True    if file exists\r
-#   @retval     False   if file doesn't exists\r
-#\r
-def ValidFile(File, Dir='.'):\r
-    Wd = os.getcwd()\r
-    os.chdir(Dir)\r
-    if not os.path.exists(File):\r
-        os.chdir(Wd)\r
-        return False\r
-    os.chdir(Wd)\r
-    return True\r
-\r
-## Get GUID value from given packages\r
-#\r
-#   @param      CName           The CName of the GUID\r
-#   @param      PackageList     List of packages looking-up in\r
-#\r
-#   @retval     GuidValue   if the CName is found in any given package\r
-#   @retval     None        if the CName is not found in all given packages\r
-#\r
-def GuidValue(CName, PackageList):\r
-    for P in PackageList:\r
-        if CName in P.Guids:\r
-            return P.Guids[CName]\r
-        if CName in P.Protocols:\r
-            return P.Protocols[CName]\r
-        if CName in P.Ppis:\r
-            return P.Ppis[CName]\r
-    return None\r
-\r
 ## Platform build information from DSC file\r
 #\r
 #  This class is used to retrieve information stored in database and convert them\r
@@ -87,14 +51,32 @@ class DscBuildData(PlatformBuildClassObject):
         MODEL_PCD_DYNAMIC_EX_VPD        :   "DynamicExVpd",\r
     }\r
 \r
+    _PROPERTY_ = {\r
+        #\r
+        # Required Fields\r
+        #\r
+        TAB_DSC_DEFINES_PLATFORM_NAME           :   "_PlatformName",\r
+        TAB_DSC_DEFINES_PLATFORM_GUID           :   "_Guid",\r
+        TAB_DSC_DEFINES_PLATFORM_VERSION        :   "_Version",\r
+        TAB_DSC_DEFINES_DSC_SPECIFICATION       :   "_DscSpecification",\r
+        #TAB_DSC_DEFINES_OUTPUT_DIRECTORY        :   "_OutputDirectory",\r
+        #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES :   "_SupArchList",\r
+        #TAB_DSC_DEFINES_BUILD_TARGETS           :   "_BuildTargets",\r
+        #TAB_DSC_DEFINES_SKUID_IDENTIFIER        :   "_SkuName",\r
+        #TAB_DSC_DEFINES_FLASH_DEFINITION        :   "_FlashDefinition",\r
+        TAB_DSC_DEFINES_BUILD_NUMBER            :   "_BuildNumber",\r
+        TAB_DSC_DEFINES_MAKEFILE_NAME           :   "_MakefileName",\r
+        TAB_DSC_DEFINES_BS_BASE_ADDRESS         :   "_BsBaseAddress",\r
+        TAB_DSC_DEFINES_RT_BASE_ADDRESS         :   "_RtBaseAddress",\r
+    }\r
+\r
     # used to compose dummy library class name for those forced library instances\r
     _NullLibraryNumber = 0\r
-    _NullLibraryClass = {}  # file : class\r
 \r
-    def __init__(self, FilePath, Table, Db, Arch='COMMON', Macros={}):\r
+    def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}):\r
         self.DescFilePath = FilePath\r
-        self._Table = Table\r
-        self._Db = Db\r
+        self._RawData = RawData\r
+        self._Bdb = BuildDataBase\r
         self._Arch = Arch\r
         self._Macros = Macros\r
         self._Clear()\r
@@ -106,15 +88,15 @@ class DscBuildData(PlatformBuildClassObject):
         S += "\tVer = %s\n" % self.Version\r
         S += "\n"\r
         S += "\tSpecification = %s\n" % self.DscSpecification\r
-        S += "\tOutputDirectory = %s\n" % self.OutputDirectory\r
-        S += "\tSupArchList = %s\n" % self.SupArchList\r
-        S += "\tBuildTargets = %s\n" % self.BuildTargets\r
-        S += "\tSkuName = %s\n" % self.SkuName\r
-        S += "\tFlashDefinition = %s\n" % self.FlashDefinition\r
-        S += "\tBuildNumber = %s\n" % self.BuildNumber\r
-        S += "\tMakefileName = %s\n" % self.MakefileName\r
-        S += "\tBsBaseAddress = %s\n" % self.BsBaseAddress\r
-        S += "\tRtBaseAddress = %s\n" % self.RtBaseAddress\r
+        S += "\tOutputDirectory = %s\n" % self.OutputDirectory \r
+        S += "\tSupArchList = %s\n" % self.SupArchList     \r
+        S += "\tBuildTargets = %s\n" % self.BuildTargets    \r
+        S += "\tSkuName = %s\n" % self.SkuName           \r
+        S += "\tFlashDefinition = %s\n" % self.FlashDefinition \r
+        S += "\tBuildNumber = %s\n" % self.BuildNumber     \r
+        S += "\tMakefileName = %s\n" % self.MakefileName    \r
+        S += "\tBsBaseAddress = %s\n" % self.BsBaseAddress   \r
+        S += "\tRtBaseAddress = %s\n" % self.RtBaseAddress   \r
 \r
         S += '  <SkuId>\n'\r
         for SkuName in self.SkuIds:\r
@@ -133,13 +115,13 @@ class DscBuildData(PlatformBuildClassObject):
         #for LibraryClass in LibraryClassList:\r
         #    for ModuleType in ModuleTypeList:\r
         #        if not (LibraryClass,ModuleType) in self.LibraryClasses:\r
-        #            continue\r
+        #            continue \r
         #        S += "\t%32s, %-24s = %s\n" % (LibraryClass, ModuleType, self.LibraryClasses[LibraryClass,ModuleType])\r
-\r
+        \r
         S += '  <PCD>\n'\r
         for Name, Guid in self.Pcds:\r
             S += "\t%s.%s\n\t\t%s\n" % (Guid, Name, str(self.Pcds[Name, Guid]))\r
-\r
+        \r
         S += '  <BuildOption>\n'\r
         for ToolChainFamily,ToolChain in self.BuildOptions:\r
             S += "\t%s:%s = %s\n" % (ToolChainFamily, ToolChain, self.BuildOptions[ToolChainFamily, ToolChain])\r
@@ -148,7 +130,18 @@ class DscBuildData(PlatformBuildClassObject):
         S += "\t" + "\n\t".join([str(M) for M in self.Modules]) + '\n'\r
         return S\r
 \r
+    ## XXX[key] = value\r
+    def __setitem__(self, key, value):\r
+        self.__dict__[self._PROPERTY_[key]] = value\r
+    ## value = XXX[key]\r
+    def __getitem__(self, key):\r
+        return self.__dict__[self._PROPERTY_[key]]\r
+    ## "in" test support\r
+    def __contains__(self, key):\r
+        return key in self._PROPERTY_\r
+\r
     def _Clear(self):\r
+        self._Header            = None\r
         self._PlatformName      = None\r
         self._Guid              = None\r
         self._Version           = None\r
@@ -166,7 +159,6 @@ class DscBuildData(PlatformBuildClassObject):
         self._Modules           = None\r
         self._LibraryInstances  = None\r
         self._LibraryClasses    = None\r
-        self._Libraries         = None\r
         self._Pcds              = None\r
         self._BuildOptions      = None\r
 \r
@@ -179,77 +171,86 @@ class DscBuildData(PlatformBuildClassObject):
         self._Arch = Value\r
         self._Clear()\r
 \r
+    def _GetHeaderInfo(self):\r
+        RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r
+        for Record in RecordList:\r
+            Name = Record[0]\r
+            if Name in self:\r
+                self[Name] = Record[1]\r
+            elif Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:\r
+                self._OutputDirectory = NormPath(Record[1], self._Macros)\r
+            elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:\r
+                self._FlashDefinition = NormPath(Record[1], self._Macros)\r
+            elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r
+                self._SupArchList = GetSplitValueList(Record[1], TAB_VALUE_SPLIT)\r
+            elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
+                self._BuildTargets = GetSplitValueList(Record[1])\r
+            elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:\r
+                if self._SkuName == None:\r
+                    self._SkuName = Record[1]\r
+        self._Header = 'DUMMY'\r
+\r
     def _GetPlatformName(self):\r
         if self._PlatformName == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_PLATFORM_NAME, self.Arch)\r
-            if len(RecordList) == 0 or RecordList[0][0] == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._PlatformName == None:\r
                 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.DescFilePath)\r
-            self._PlatformName = RecordList[0][0]\r
         return self._PlatformName\r
 \r
     def _GetFileGuid(self):\r
         if self._Guid == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_PLATFORM_GUID, self.Arch)\r
-            if len(RecordList) == 0 or RecordList[0][0] == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._Guid == None:\r
                 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No FILE_GUID", File=self.DescFilePath)\r
-            self._Guid = RecordList[0][0]\r
         return self._Guid\r
 \r
     def _GetVersion(self):\r
         if self._Version == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_PLATFORM_VERSION, self.Arch)\r
-            if len(RecordList) == 0 or RecordList[0][0] == None:\r
-                self._Version = 0.0\r
-            else:\r
-                self._Version = RecordList[0][0]\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._Version == None:\r
+                self._Version = ''\r
         return self._Version\r
 \r
     def _GetDscSpec(self):\r
         if self._DscSpecification == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_DSC_SPECIFICATION, self.Arch)\r
-            if len(RecordList) == 0 or RecordList[0][0] == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._DscSpecification == None:\r
                 self._DscSpecification = ''\r
-            else:\r
-                self._DscSpecification = RecordList[0][0]\r
         return self._DscSpecification\r
 \r
     def _GetOutpuDir(self):\r
         if self._OutputDirectory == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_OUTPUT_DIRECTORY, self.Arch)\r
-            if len(RecordList) == 0 or RecordList[0][0] == None:\r
-                self._OutputDirectory = os.path.join("Build", self.PlatformName)\r
-            else:\r
-                File = NormPath(RecordList[0][0], self._Macros)\r
-                LineNo = RecordList[0][-1]\r
-                self._OutputDirectory = File\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._OutputDirectory == None:\r
+                self._OutputDirectory = os.path.join("Build", self._PlatformName)\r
         return self._OutputDirectory\r
 \r
     def _GetSupArch(self):\r
         if self._SupArchList == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES, self.Arch)\r
-            if len(RecordList) == 0 or RecordList[0][0] == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._SupArchList == None:\r
                 self._SupArchList = ARCH_LIST\r
-            else:\r
-                self._SupArchList = GetSplitValueList(RecordList[0][0], TAB_VALUE_SPLIT)\r
         return self._SupArchList\r
 \r
     def _GetBuildTarget(self):\r
         if self._BuildTargets == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_BUILD_TARGETS, self.Arch)\r
-            if len(RecordList) == 0 or RecordList[0][0] == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._BuildTargets == None:\r
                 self._BuildTargets = ['DEBUG', 'RELEASE']\r
-            else:\r
-                self._BuildTargets = GetSplitValueList(RecordList[0][0])\r
         return self._BuildTargets\r
 \r
     def _GetSkuName(self):\r
         if self._SkuName == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_SKUID_IDENTIFIER, self.Arch)\r
-            if len(RecordList) > 0:\r
-                self._SkuName = RecordList[0][0]\r
-                if self._SkuName not in self.SkuIds:\r
-                    self._SkuName = 'DEFAULT'\r
-            else:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._SkuName == None or self._SkuName not in self.SkuIds:\r
                 self._SkuName = 'DEFAULT'\r
         return self._SkuName\r
 \r
@@ -259,53 +260,48 @@ class DscBuildData(PlatformBuildClassObject):
 \r
     def _GetFdfFile(self):\r
         if self._FlashDefinition == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_FLASH_DEFINITION, self.Arch)\r
-            if len(RecordList) > 0:\r
-                self._FlashDefinition = NormPath(RecordList[0][0], self._Macros)\r
-            else:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._FlashDefinition == None:\r
                 self._FlashDefinition = ''\r
         return self._FlashDefinition\r
 \r
     def _GetBuildNumber(self):\r
         if self._BuildNumber == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_BUILD_NUMBER, self.Arch)\r
-            if len(RecordList) > 0 and RecordList[0][0] != None:\r
-                self._BuildNumber = RecordList[0][0]\r
-            else:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._BuildNumber == None:\r
                 self._BuildNumber = ''\r
         return self._BuildNumber\r
 \r
     def _GetMakefileName(self):\r
         if self._MakefileName == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_MAKEFILE_NAME, self.Arch)\r
-            if len(RecordList) > 0 and RecordList[0][0] != None:\r
-                self._MakefileName = RecordList[0][0]\r
-            else:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._MakefileName == None:\r
                 self._MakefileName = ''\r
         return self._MakefileName\r
 \r
     def _GetBsBaseAddress(self):\r
         if self._BsBaseAddress == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_BS_BASE_ADDRESS, self.Arch)\r
-            if len(RecordList) > 0 and RecordList[0][0] != None:\r
-                self._BsBaseAddress = RecordList[0][0]\r
-            else:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._BsBaseAddress == None:\r
                 self._BsBaseAddress = ''\r
         return self._BsBaseAddress\r
 \r
     def _GetRtBaseAddress(self):\r
         if self._RtBaseAddress == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DSC_DEFINES_RT_BASE_ADDRESS, self.Arch)\r
-            if len(RecordList) > 0 and RecordList[0][0] != None:\r
-                self._RtBaseAddress = RecordList[0][0]\r
-            else:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._RtBaseAddress == None:\r
                 self._RtBaseAddress = ''\r
         return self._RtBaseAddress\r
 \r
     def _GetSkuIds(self):\r
         if self._SkuIds == None:\r
             self._SkuIds = {}\r
-            RecordList = self._Table.Query(MODEL_EFI_SKU_ID)\r
+            RecordList = self._RawData[MODEL_EFI_SKU_ID]\r
             for Record in RecordList:\r
                 if Record[0] in [None, '']:\r
                     EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',\r
@@ -319,392 +315,123 @@ class DscBuildData(PlatformBuildClassObject):
         return self._SkuIds\r
 \r
     def _GetModules(self):\r
-        if self._Modules == None:\r
-            self._Modules = []\r
-            RecordList = self._Table.Query(MODEL_META_DATA_COMPONENT, Scope1=self.Arch)\r
-            for Record in RecordList:\r
-                ModuleFile = NormPath(Record[0], self._Macros)\r
-                ModuleId = Record[5]\r
-                LineNo = Record[6]\r
-                if not ValidFile(ModuleFile):\r
-                    EdkLogger.error('build', FILE_NOT_FOUND, File=self.DescFilePath,\r
-                                    ExtraData=ModuleFile, Line=LineNo)\r
-                if ModuleFile in self._Modules:\r
-                    continue\r
-                Module = self._Db.BuildObject[ModuleFile, MODEL_FILE_INF, self._Arch]\r
-                # only merge library classes and PCD for non-library module\r
-                if Module.LibraryClass == None or Module.LibraryClass == []:\r
-                    if Module.AutoGenVersion < 0x00010005:\r
-                        self._ResolveLibraryReference(Module)\r
-                    else:\r
-                        self._MergeModuleInfo(Module, ModuleId)\r
-                self._UpdateModulePcd(Module, ModuleId)\r
-                self._MergeModuleBuildOption(Module, ModuleId)\r
-                self._Modules.append(Module)\r
-        return self._Modules\r
+        if self._Modules != None:\r
+            return self._Modules\r
 \r
-    def _MergeModuleInfo(self, Module, ModuleId):\r
-        ModuleType = Module.ModuleType\r
-        # merge library class/instance information\r
-        for LibraryClass in Module.LibraryClasses:\r
-            if self.LibraryClasses[LibraryClass, ModuleType] == None: continue\r
-            Module.LibraryClasses[LibraryClass] = self.LibraryClasses[LibraryClass, ModuleType]\r
-        RecordList = self._Table.Query(MODEL_EFI_LIBRARY_CLASS, Scope1=self.Arch, BelongsToItem=ModuleId)\r
+        self._Modules = sdict()\r
+        RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r
         for Record in RecordList:\r
-            LibraryClass = Record[0]\r
-            LibraryPath = NormPath(Record[1], self._Macros)\r
-            LineNo = Record[-1]\r
-            if not ValidFile(LibraryPath):\r
-                EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=LibraryPath,\r
-                                File=self.DescFilePath, Line=LineNo)\r
-            if LibraryClass == '' or LibraryClass == 'NULL':\r
-                if LibraryPath not in DscBuildData._NullLibraryClass:\r
-                    DscBuildData._NullLibraryNumber += 1\r
-                    LibraryClass = 'NULL%d' % DscBuildData._NullLibraryNumber\r
-                    Lc = LibraryClassObject(LibraryClass, [ModuleType])\r
-                    LibraryInstance = self._Db.BuildObject[LibraryPath, MODEL_FILE_INF, self._Arch]\r
-                    LibraryInstance.LibraryClass.append(Lc)\r
-                    DscBuildData._NullLibraryClass[LibraryPath] = Lc\r
-                else:\r
-                    Lc = DscBuildData._NullLibraryClass[LibraryPath]\r
-                    LibraryClass = Lc.LibraryClass\r
-                    # add new supported module type\r
-                    if ModuleType not in Lc.SupModList:\r
-                        Lc.SupModList.append(ModuleType)\r
-                    LibraryInstance = self._Db.BuildObject[LibraryPath, MODEL_FILE_INF, self._Arch]\r
-                    LibraryInstance.LibraryClass.append(Lc)\r
-\r
-            Module.LibraryClasses[LibraryClass] = LibraryPath\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.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._Db.BuildObject[LibraryPath, MODEL_FILE_INF, self._Arch]\r
-                    LibraryInstance[LibraryClassName] = LibraryModule\r
-                    LibraryConsumerList.append(LibraryModule)\r
-                    EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))\r
-                else:\r
-                    LibraryModule = LibraryInstance[LibraryClassName]\r
-                if LibraryModule == None: 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
-                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
-                                "\tLibrary instance of library class [%s] is not found" % LibraryClassName,\r
-                                File=self.DescFilePath, ExtraData="consumed by [%s] [%s]" % (str(Module), self._Arch))\r
-            LibraryList.append(M)\r
-            #\r
-            # check if there're duplicate 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.DescFilePath, 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.DescFilePath)\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
-        Module.LibraryClasses = sdict()\r
-        for L in SortedLibraryList:\r
-            Module.LibraryClasses[L.LibraryClass[0].LibraryClass, ModuleType] = L\r
-            #\r
-            # Merge PCDs from library instance\r
-            #\r
-            for Key in L.Pcds:\r
-                if Key not in Module.Pcds:\r
-                    Module.Pcds[Key] = L.Pcds[Key]\r
-            #\r
-            # Merge GUIDs from library instance\r
-            #\r
-            for CName in L.Guids:\r
-                if CName not in Module.Guids:\r
-                    Module.Guids[CName] = L.Guids[CName]\r
-            #\r
-            # Merge Protocols from library instance\r
-            #\r
-            for CName in L.Protocols:\r
-                if CName not in Module.Protocols:\r
-                    Module.Protocols[CName] = L.Protocols[CName]\r
-            #\r
-            # Merge Ppis from library instance\r
-            #\r
-            for CName in L.Ppis:\r
-                if CName not in Module.Ppis:\r
-                    Module.Ppis[CName] = L.Ppis[CName]\r
-\r
-    ##\r
-    # for R8.x 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
-        while len(LibraryConsumerList) > 0:\r
-            M = LibraryConsumerList.pop()\r
-            for LibraryName in M.Libraries:\r
-                if LibraryName not in self.Libraries:\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
+            ModuleFile = NormPath(Record[0], self._Macros)\r
+            ModuleId = Record[5]\r
+            LineNo = Record[6]\r
+            if not ValidFile(ModuleFile):\r
+                EdkLogger.error('build', FILE_NOT_FOUND, File=self.DescFilePath, \r
+                                ExtraData=ModuleFile, Line=LineNo)\r
+            if ModuleFile in self._Modules:\r
+                continue\r
+            Module = ModuleBuildClassObject()\r
+            Module.DescFilePath = ModuleFile\r
 \r
-                Library = self.Libraries[LibraryName]\r
-                if (LibraryName, Module.ModuleType) not in Module.LibraryClasses:\r
-                    Module.LibraryClasses[LibraryName, Module.ModuleType] = Library\r
-                    LibraryConsumerList.append(Library)\r
-                    EdkLogger.verbose("\t" + LibraryName + " : " + str(Library))\r
-\r
-    def _UpdateModulePcd(self, Module, ModuleId):\r
-        for Name,Guid in Module.Pcds:\r
-            PcdInModule = Module.Pcds[Name,Guid]\r
-            if (Name,Guid) in self.Pcds:\r
-                PcdInPlatform = self.Pcds[Name,Guid]\r
-                #\r
-                # in case there's PCDs coming from FDF file, which have no type given.\r
-                # at this point, PcdInModule.Type has the type found from dependent\r
-                # package\r
-                #\r
-                if PcdInPlatform.Type != None and PcdInPlatform.Type != '':\r
-                    PcdInModule.Type = PcdInPlatform.Type\r
-                PcdInModule.MaxDatumSize = PcdInPlatform.MaxDatumSize\r
-                PcdInModule.SkuInfoList = PcdInPlatform.SkuInfoList\r
-                if PcdInPlatform.DefaultValue not in [None, '']:\r
-                    PcdInModule.DefaultValue = PcdInPlatform.DefaultValue\r
-                if PcdInPlatform.TokenValue not in [None, '']:\r
-                    PcdInModule.TokenValue = PcdInPlatform.TokenValue\r
-                if PcdInPlatform.MaxDatumSize not in [None, '']:\r
-                    PcdInModule.MaxDatumSize = PcdInPlatform.MaxDatumSize\r
-                if PcdInPlatform.DatumType not in [None, '']:\r
-                    PcdInModule.DatumType = PcdInPlatform.DatumType\r
-\r
-            if PcdInModule.DatumType == "VOID*" and PcdInModule.MaxDatumSize in ['', None]:\r
-                EdkLogger.verbose("No MaxDatumSize specified for PCD %s.%s in module [%s]" % (Guid, Name, str(Module)))\r
-                Value = PcdInModule.DefaultValue\r
-                if Value[0] == 'L':\r
-                    PcdInModule.MaxDatumSize = str(len(Value) * 2)\r
-                elif Value[0] == '{':\r
-                    PcdInModule.MaxDatumSize = str(len(Value.split(',')))\r
-                else:\r
-                    PcdInModule.MaxDatumSize = str(len(Value))\r
+            # get module private library instance\r
+            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]\r
+            for Record in RecordList:\r
+                LibraryClass = Record[0]\r
+                LibraryPath = NormPath(Record[1], self._Macros)\r
+                LineNo = Record[-1]\r
+                if not ValidFile(LibraryPath):\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=LibraryPath,\r
+                                    File=self.DescFilePath, Line=LineNo)\r
+                if LibraryClass == '' or LibraryClass == 'NULL':\r
+                    self._NullLibraryNumber += 1\r
+                    LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
+                    EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))\r
+                Module.LibraryClasses[LibraryClass] = LibraryPath\r
+                if LibraryPath not in self.LibraryInstances:\r
+                    self.LibraryInstances.append(LibraryPath)\r
+\r
+            # get module private PCD setting\r
+            for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \\r
+                         MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:\r
+                RecordList = self._RawData[Type, self._Arch, None, ModuleId]\r
+                for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
+                    TokenList = GetSplitValueList(Setting)\r
+                    DefaultValue = TokenList[0]\r
+                    if len(TokenList) > 1:\r
+                        MaxDatumSize = TokenList[1]\r
+                    else:\r
+                        MaxDatumSize = ''\r
+                    Type = self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD]\r
+                    Pcd = PcdClassObject(\r
+                            PcdCName,\r
+                            TokenSpaceGuid,\r
+                            Type,\r
+                            '',\r
+                            DefaultValue,\r
+                            '',\r
+                            MaxDatumSize,\r
+                            {},\r
+                            None\r
+                            )\r
+                    Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
 \r
-            # apply default SKU for dynamic PCDS if specified one is not available\r
-            if (PcdInModule.Type in PCD_DYNAMIC_TYPE_LIST or PcdInModule.Type in PCD_DYNAMIC_EX_TYPE_LIST) \\r
-                and PcdInModule.SkuInfoList in [None, {}, '']:\r
-                if self.SkuName in self.SkuIds:\r
-                    SkuName = self.SkuName\r
+            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]\r
+            for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
+                if (ToolChainFamily, ToolChain) not in Module.BuildOptions:\r
+                    Module.BuildOptions[ToolChainFamily, ToolChain] = Option\r
                 else:\r
-                    SkuName = 'DEFAULT'\r
-                PcdInModule.SkuInfoList = {\r
-                    SkuName : SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdInModule.DefaultValue)\r
-                }\r
-\r
-        RecordList = self._Table.Query(MODEL_PCD_FIXED_AT_BUILD, Scope1=self.Arch, BelongsToItem=ModuleId)\r
-        for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-            if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
-                continue\r
-            TokenList = GetSplitValueList(Setting)\r
-            Pcd = Module.Pcds[PcdCName, TokenSpaceGuid]\r
-            Pcd.DefaultValue = TokenList[0]\r
-            if len(TokenList) > 1:\r
-                Pcd.MaxDatumSize = TokenList[1]\r
-            Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD]\r
-\r
-        RecordList = self._Table.Query(MODEL_PCD_PATCHABLE_IN_MODULE, Scope1=self.Arch, BelongsToItem=ModuleId)\r
-        for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-            if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
-                continue\r
-            TokenList = GetSplitValueList(Setting)\r
-            Pcd = Module.Pcds[PcdCName, TokenSpaceGuid]\r
-            Pcd.DefaultValue = TokenList[0]\r
-            if len(TokenList) > 1:\r
-                Pcd.MaxDatumSize = TokenList[1]\r
-            Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]\r
-\r
-        RecordList = self._Table.Query(MODEL_PCD_FEATURE_FLAG, Scope1=self.Arch, BelongsToItem=ModuleId)\r
-        for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-            if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
-                continue\r
-            TokenList = GetSplitValueList(Setting)\r
-            Pcd = Module.Pcds[PcdCName, TokenSpaceGuid]\r
-            Pcd.DefaultValue = TokenList[0]\r
-            if len(TokenList) > 1:\r
-                Pcd.MaxDatumSize = TokenList[1]\r
-            Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]\r
-\r
-        RecordList = self._Table.Query(MODEL_PCD_DYNAMIC, Scope1=self.Arch, BelongsToItem=ModuleId)\r
-        for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-            if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
-                continue\r
-            Pcd.DefaultValue = Setting\r
-            Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC]\r
+                    OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]\r
+                    Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
 \r
-        RecordList = self._Table.Query(MODEL_PCD_DYNAMIC_EX, Scope1=self.Arch, BelongsToItem=ModuleId)\r
-        for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-            if (PcdCName, TokenSpaceGuid) not in Module.Pcds:\r
-                continue\r
-            Pcd.DefaultValue = Setting\r
-            Pcd.Type = self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]\r
-\r
-    def _MergeModuleBuildOption(self, Module, ModuleId):\r
-        RecordList = self._Table.Query(MODEL_META_DATA_BUILD_OPTION, Scope1=self.Arch, BelongsToItem=ModuleId)\r
-        for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-            if (ToolChainFamily, ToolChain) not in Module.BuildOptions:\r
-                Module.BuildOptions[ToolChainFamily, ToolChain] = Option\r
-            else:\r
-                OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]\r
-                Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
+            self._Modules[ModuleFile] = Module\r
+        return self._Modules\r
 \r
     def _GetLibraryInstances(self):\r
         if self._LibraryInstances == None:\r
-            self._LibraryInstances = []\r
-            for Module in self.Modules:\r
-                for Key in Module.LibraryClasses:\r
-                    Lib = Module.LibraryClasses[Key]\r
-                    if Lib in [None, ''] or Lib in self._LibraryInstances:\r
-                        continue\r
-                    self._LibraryInstances.append(Lib)\r
+            self._GetLibraryClasses()\r
         return self._LibraryInstances\r
 \r
     def _GetLibraryClasses(self):\r
         if self._LibraryClasses == None:\r
+            self._LibraryInstances = []\r
             LibraryClassDict = tdict(True, 3)\r
             LibraryClassSet = set()\r
-            ModuleTypeSet = set()\r
-            RecordList = self._Table.Query(MODEL_EFI_LIBRARY_CLASS, Scope1=self.Arch)\r
+            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
             for LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo in RecordList:\r
                 LibraryClassSet.add(LibraryClass)\r
-                ModuleTypeSet.add(ModuleType)\r
                 LibraryInstance = NormPath(LibraryInstance, self._Macros)\r
                 if not ValidFile(LibraryInstance):\r
-                    EdkLogger.error('build', FILE_NOT_FOUND, File=self.DescFilePath,\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, File=self.DescFilePath, \r
                                     ExtraData=LibraryInstance, Line=LineNo)\r
                 LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance\r
+                if LibraryInstance not in self._LibraryInstances:\r
+                    self._LibraryInstances.append(LibraryInstance)\r
 \r
+            # resolve the specific library instance for each class and each module type \r
             self._LibraryClasses = tdict(True)\r
             for LibraryClass in LibraryClassSet:\r
-                for ModuleType in ModuleTypeSet:\r
-                    LibraryInstance = LibraryClassDict[self.Arch, ModuleType, LibraryClass]\r
+                for ModuleType in SUP_MODULE_LIST:\r
+                    LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]\r
                     if LibraryInstance == None:\r
                         continue\r
                     self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance\r
-        return self._LibraryClasses\r
 \r
-    def _GetLibraries(self):\r
-        if self._Libraries == None:\r
-            self._Libraries = sdict()\r
-            RecordList = self._Table.Query(MODEL_EFI_LIBRARY_INSTANCE, Scope1=self.Arch)\r
+            # for R8 style library instances\r
+            RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]\r
             for Record in RecordList:\r
                 File = NormPath(Record[0], self._Macros)\r
                 LineNo = Record[-1]\r
                 if not ValidFile(File):\r
                     EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
                                     File=self.DescFilePath, Line=LineNo)\r
-                Library = self._Db.BuildObject[File, MODEL_FILE_INF, self._Arch]\r
-                self._Libraries[Library.BaseName] = Library\r
-        return self._Libraries\r
+                if File not in self._LibraryInstances:\r
+                    self._LibraryInstances.append(File)\r
+                # \r
+                # we need the module name as the library class name, so we have\r
+                # to parse it here\r
+                # \r
+                Library = self._Bdb[File, self._Arch]\r
+                self._LibraryClasses[Library.BaseName, ':dummy:'] = Library\r
+        return self._LibraryClasses\r
 \r
     def _GetPcds(self):\r
         if self._Pcds == None:\r
@@ -723,7 +450,7 @@ class DscBuildData(PlatformBuildClassObject):
     def _GetBuildOptions(self):\r
         if self._BuildOptions == None:\r
             self._BuildOptions = {}\r
-            RecordList = self._Table.Query(MODEL_META_DATA_BUILD_OPTION)\r
+            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION]\r
             for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
                 self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
         return self._BuildOptions\r
@@ -732,15 +459,15 @@ class DscBuildData(PlatformBuildClassObject):
         Pcds = {}\r
         PcdDict = tdict(True, 3)\r
         PcdSet = set()\r
-        # Find out all possible PCD candidates for self.Arch\r
-        RecordList = self._Table.Query(Type, Scope1=self.Arch)\r
+        # Find out all possible PCD candidates for self._Arch\r
+        RecordList = self._RawData[Type, self._Arch]\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
             PcdSet.add((PcdCName, TokenSpaceGuid))\r
             PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
         # Remove redundant PCD candidates\r
         for PcdCName, TokenSpaceGuid in PcdSet:\r
             ValueList = ['', '', '']\r
-            Setting = PcdDict[self.Arch, PcdCName, TokenSpaceGuid]\r
+            Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
             TokenList = Setting.split(TAB_VALUE_SPLIT)\r
@@ -755,7 +482,7 @@ class DscBuildData(PlatformBuildClassObject):
                                                 '',\r
                                                 MaxDatumSize,\r
                                                 {},\r
-                                                True\r
+                                                None\r
                                                 )\r
         return Pcds\r
 \r
@@ -763,14 +490,14 @@ class DscBuildData(PlatformBuildClassObject):
         Pcds = {}\r
         PcdDict = tdict(True, 4)\r
         PcdSet = set()\r
-        RecordList = self._Table.Query(Type, Scope1=self.Arch)\r
+        RecordList = self._RawData[Type, self._Arch]\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
             PcdSet.add((PcdCName, TokenSpaceGuid))\r
             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
 \r
         for PcdCName, TokenSpaceGuid in PcdSet:\r
             ValueList = ['', '', '']\r
-            Setting = PcdDict[self.Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
+            Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
             TokenList = Setting.split(TAB_VALUE_SPLIT)\r
@@ -787,7 +514,7 @@ class DscBuildData(PlatformBuildClassObject):
                                                 '',\r
                                                 MaxDatumSize,\r
                                                 {self.SkuName : SkuInfo},\r
-                                                True\r
+                                                None\r
                                                 )\r
         return Pcds\r
 \r
@@ -795,14 +522,14 @@ class DscBuildData(PlatformBuildClassObject):
         Pcds = {}\r
         PcdDict = tdict(True, 4)\r
         PcdSet = set()\r
-        RecordList = self._Table.Query(Type, Scope1=self.Arch)\r
+        RecordList = self._RawData[Type, self._Arch]\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
             PcdSet.add((PcdCName, TokenSpaceGuid))\r
             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
 \r
         for PcdCName, TokenSpaceGuid in PcdSet:\r
             ValueList = ['', '', '', '']\r
-            Setting = PcdDict[self.Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
+            Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
             TokenList = Setting.split(TAB_VALUE_SPLIT)\r
@@ -818,7 +545,7 @@ class DscBuildData(PlatformBuildClassObject):
                                                 '',\r
                                                 '',\r
                                                 {self.SkuName : SkuInfo},\r
-                                                True\r
+                                                None\r
                                                 )\r
         return Pcds\r
 \r
@@ -826,14 +553,14 @@ class DscBuildData(PlatformBuildClassObject):
         Pcds = {}\r
         PcdDict = tdict(True, 4)\r
         PcdSet = set()\r
-        RecordList = self._Table.Query(Type, Scope1=self.Arch)\r
+        RecordList = self._RawData[Type, self._Arch]\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
             PcdSet.add((PcdCName, TokenSpaceGuid))\r
             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
 \r
         for PcdCName, TokenSpaceGuid in PcdSet:\r
             ValueList = ['', '']\r
-            Setting = PcdDict[self.Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
+            Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
             TokenList = Setting.split(TAB_VALUE_SPLIT)\r
@@ -850,13 +577,16 @@ class DscBuildData(PlatformBuildClassObject):
                                                 '',\r
                                                 MaxDatumSize,\r
                                                 {self.SkuName : SkuInfo},\r
-                                                True\r
+                                                None\r
                                                 )\r
         return Pcds\r
 \r
     def AddModule(self, FilePath):\r
-        Module = self._Db.BuildObject[FilePath, MODEL_FILE_INF, self._Arch]\r
-        self._Modules.append(NormPath(Module))\r
+        FilePath = NormPath(FilePath)\r
+        if FilePath not in self.Modules:\r
+            Module = ModuleBuildClassObject()\r
+            Module.DescFilePath = FilePath\r
+            self.Modules.append(Module)\r
 \r
     def AddPcd(self, Name, Guid, Value):\r
         if (Name, Guid) not in self.Pcds:\r
@@ -869,7 +599,7 @@ class DscBuildData(PlatformBuildClassObject):
                                         '',\r
                                         '',\r
                                         {},\r
-                                        True\r
+                                        None\r
                                         )\r
         self.Pcds[Name, Guid].DefaultValue = Value\r
 \r
@@ -893,7 +623,6 @@ class DscBuildData(PlatformBuildClassObject):
     Modules             = property(_GetModules)\r
     LibraryInstances    = property(_GetLibraryInstances)\r
     LibraryClasses      = property(_GetLibraryClasses)\r
-    Libraries           = property(_GetLibraries)\r
     Pcds                = property(_GetPcds)\r
     BuildOptions        = property(_GetBuildOptions)\r
 \r
@@ -912,11 +641,23 @@ class DecBuildData(PackageBuildClassObject):
         MODEL_PCD_DYNAMIC_EX_VPD        :   "DynamicExVpd",\r
     }\r
 \r
-    def __init__(self, FilePath, Table, Db, Arch='COMMON', Macros={}):\r
+    _PROPERTY_ = {\r
+        #\r
+        # Required Fields\r
+        #\r
+        TAB_DEC_DEFINES_PACKAGE_NAME                : "_PackageName",\r
+        TAB_DEC_DEFINES_PACKAGE_GUID                : "_Guid",\r
+        TAB_DEC_DEFINES_PACKAGE_VERSION             : "_Version",\r
+    }\r
+\r
+\r
+    def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Platform='COMMON', Macros={}):\r
         self.DescFilePath = FilePath\r
         self._PackageDir = os.path.dirname(FilePath)\r
-        self._Table = Table\r
+        self._RawData = RawData\r
+        self._Bdb = BuildDataBase\r
         self._Arch = Arch\r
+        self._Platform = Platform\r
         self._Macros = Macros\r
         self._Clear()\r
 \r
@@ -950,7 +691,18 @@ class DecBuildData(PackageBuildClassObject):
             S += "\t%s.%s-%s\n\t\t%s\n" % (Guid, Name, Type, str(self.Pcds[Name, Guid, Type]))\r
         return S\r
 \r
+    ## XXX[key] = value\r
+    def __setitem__(self, key, value):\r
+        self.__dict__[self._PROPERTY_[key]] = value\r
+    ## value = XXX[key]\r
+    def __getitem__(self, key):\r
+        return self.__dict__[self._PROPERTY_[key]]\r
+    ## "in" test support\r
+    def __contains__(self, key):\r
+        return key in self._PROPERTY_\r
+\r
     def _Clear(self):\r
+        self._Header            = None\r
         self._PackageName       = None\r
         self._Guid              = None\r
         self._Version           = None\r
@@ -970,76 +722,84 @@ class DecBuildData(PackageBuildClassObject):
         self._Arch = Value\r
         self._Clear()\r
 \r
+    def _GetHeaderInfo(self):\r
+        RecordList = self._RawData[MODEL_META_DATA_HEADER]\r
+        for Record in RecordList:\r
+            Name = Record[0]\r
+            if Name in self:\r
+                self[Name] = Record[1]\r
+        self._Header = 'DUMMY'\r
+\r
     def _GetPackageName(self):\r
         if self._PackageName == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DEC_DEFINES_PACKAGE_NAME)\r
-            if len(RecordList) == 0:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._PackageName == None:\r
                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.DescFilePath)\r
-            self._PackageName = RecordList[0][0]\r
         return self._PackageName\r
 \r
     def _GetFileGuid(self):\r
         if self._Guid == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DEC_DEFINES_PACKAGE_GUID)\r
-            if len(RecordList) == 0:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._Guid == None:\r
                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.DescFilePath)\r
-            self._Guid = RecordList[0][0]\r
         return self._Guid\r
 \r
     def _GetVersion(self):\r
         if self._Version == None:\r
-            RecordList = self._Table.Query(MODEL_META_DATA_HEADER, TAB_DEC_DEFINES_PACKAGE_VERSION)\r
-            if len(RecordList) == 0:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._Version == None:\r
                 self._Version = ''\r
-            self._Version = RecordList[0][0]\r
         return self._Version\r
 \r
     def _GetProtocol(self):\r
         if self._Protocols == None:\r
             ProtocolDict = tdict(True)\r
             NameList = []\r
-            RecordList = self._Table.Query(MODEL_EFI_PROTOCOL, Arch=self.Arch)\r
+            RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]\r
             for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
                 if Name not in NameList:\r
                     NameList.append(Name)\r
                 ProtocolDict[Arch, Name] = Guid\r
             self._Protocols = sdict()\r
             for Name in NameList:\r
-                self._Protocols[Name] = ProtocolDict[self.Arch, Name]\r
+                self._Protocols[Name] = ProtocolDict[self._Arch, Name]\r
         return self._Protocols\r
 \r
     def _GetPpi(self):\r
         if self._Ppis == None:\r
             PpiDict = tdict(True)\r
             NameList = []\r
-            RecordList = self._Table.Query(MODEL_EFI_PPI, Arch=self.Arch)\r
+            RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]\r
             for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
                 if Name not in NameList:\r
                     NameList.append(Name)\r
                 PpiDict[Arch, Name] = Guid\r
             self._Ppis = sdict()\r
             for Name in NameList:\r
-                self._Ppis[Name] = PpiDict[self.Arch, Name]\r
+                self._Ppis[Name] = PpiDict[self._Arch, Name]\r
         return self._Ppis\r
 \r
     def _GetGuid(self):\r
         if self._Guids == None:\r
             GuidDict = tdict(True)\r
             NameList = []\r
-            RecordList = self._Table.Query(MODEL_EFI_GUID, Arch=self.Arch)\r
+            RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]\r
             for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
                 if Name not in NameList:\r
                     NameList.append(Name)\r
                 GuidDict[Arch, Name] = Guid\r
             self._Guids = sdict()\r
             for Name in NameList:\r
-                self._Guids[Name] = GuidDict[self.Arch, Name]\r
+                self._Guids[Name] = GuidDict[self._Arch, Name]\r
         return self._Guids\r
 \r
     def _GetInclude(self):\r
         if self._Includes == None:\r
             self._Includes = []\r
-            RecordList = self._Table.Query(MODEL_EFI_INCLUDE, Arch=self.Arch)\r
+            RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]\r
             for Record in RecordList:\r
                 File = NormPath(Record[0], self._Macros)\r
                 LineNo = Record[-1]\r
@@ -1054,7 +814,7 @@ class DecBuildData(PackageBuildClassObject):
         if self._LibraryClasses == None:\r
             LibraryClassDict = tdict(True)\r
             LibraryClassSet = set()\r
-            RecordList = self._Table.Query(MODEL_EFI_LIBRARY_CLASS, Arch=self.Arch)\r
+            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
             for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList:\r
                 File = NormPath(File, self._Macros)\r
                 if not ValidFile(File, self._PackageDir):\r
@@ -1064,7 +824,7 @@ class DecBuildData(PackageBuildClassObject):
                 LibraryClassDict[Arch, LibraryClass] = File\r
             self._LibraryClasses = sdict()\r
             for LibraryClass in LibraryClassSet:\r
-                self._LibraryClasses[LibraryClass] = LibraryClassDict[self.Arch, LibraryClass]\r
+                self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]\r
         return self._LibraryClasses\r
 \r
     def _GetPcds(self):\r
@@ -1081,14 +841,14 @@ class DecBuildData(PackageBuildClassObject):
         Pcds = {}\r
         PcdDict = tdict(True, 3)\r
         PcdSet = set()\r
-        RecordList = self._Table.Query(Type, Arch=self._Arch)\r
+        RecordList = self._RawData[Type, self._Arch]\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, Dummy1, Dummy2 in RecordList:\r
             PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
             PcdSet.add((PcdCName, TokenSpaceGuid))\r
 \r
         for PcdCName, TokenSpaceGuid in PcdSet:\r
             ValueList = ['', '', '']\r
-            Setting = PcdDict[self.Arch, PcdCName, TokenSpaceGuid]\r
+            Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
             TokenList = Setting.split(TAB_VALUE_SPLIT)\r
@@ -1103,7 +863,7 @@ class DecBuildData(PackageBuildClassObject):
                                                                             TokenNumber,\r
                                                                             '',\r
                                                                             {},\r
-                                                                            True\r
+                                                                            None\r
                                                                             )\r
         return Pcds\r
 \r
@@ -1172,27 +932,27 @@ class InfBuildData(ModuleBuildClassObject):
         "APPLICATION"           :   "UEFI_APPLICATION",\r
         "LOGO"                  :   "BASE",\r
     }\r
-\r
+    \r
     _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)\r
     _TOOL_CODE_ = {\r
         "C"         :   "CC",\r
         "LIB"       :   "SLINK",\r
         "LINK"      :   "DLINK",\r
     }\r
+    \r
 \r
-\r
-    def __init__(self, FilePath, Table, Db, Arch='COMMON', Macros={}):\r
+    def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Platform='COMMON', Macros={}):\r
         self.DescFilePath = FilePath\r
         self._ModuleDir = os.path.dirname(FilePath)\r
-        self._Table = Table\r
-        self._Db = Db\r
+        self._RawData = RawData\r
+        self._Bdb = BuildDatabase\r
         self._Arch = Arch\r
         self._Platform = 'COMMON'\r
         self._Macros = Macros\r
         self._Clear()\r
 \r
     def Print(self):\r
-        S = '[%s.%s]\n' % (self.DescFilePath, self.Arch)\r
+        S = '[%s.%s]\n' % (self.DescFilePath, self._Arch)\r
         S += '\tName = ' + self.BaseName + '\n'\r
         S += '\tGuid = ' + self.Guid + '\n'\r
         S += '\tVer  = ' + self.Version + '\n'\r
@@ -1309,7 +1069,7 @@ class InfBuildData(ModuleBuildClassObject):
         self._Platform = Value\r
 \r
     def _GetHeaderInfo(self):\r
-        RecordList = self._Table.Query(MODEL_META_DATA_HEADER, Arch=self._Arch, Platform=self._Platform)\r
+        RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
         for Record in RecordList:\r
             Name = Record[0]\r
             if Name in self:\r
@@ -1356,26 +1116,28 @@ class InfBuildData(ModuleBuildClassObject):
                 self._DestructorList.append(Record[1])\r
             elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:\r
                 TokenList = GetSplitValueList(Record[1])\r
-                self._CustomMakefile = {}\r
+                if self._CustomMakefile == None:\r
+                    self._CustomMakefile = {}\r
                 if len(TokenList) < 2:\r
                     self._CustomMakefile['MSFT'] = TokenList[0]\r
                     self._CustomMakefile['GCC'] = TokenList[0]\r
                 else:\r
                     if TokenList[0] not in ['MSFT', 'GCC']:\r
                         EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
-                                        "No supported family [%s]" % TokenList[0],\r
+                                        "No supported family [%s]" % TokenList[0], \r
                                         File=self.DescFilePath, Line=Record[-1])\r
                     self._CustomMakefile[TokenList[0]] = TokenList[1]\r
-        #\r
+\r
+        # \r
         # R8.x modules\r
-        #\r
+        # \r
         if self._AutoGenVersion < 0x00010005:   # _AutoGenVersion may be None, which is less than anything\r
             if self._ComponentType in self._MODULE_TYPE_:\r
                 self._ModuleType = self._MODULE_TYPE_[self._ComponentType]\r
             if self._ComponentType == 'LIBRARY':\r
                 self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]\r
             # make use some [nmake] section macros\r
-            RecordList = self._Table.Query(MODEL_META_DATA_NMAKE, Arch=self._Arch, Platform=self._Platform)\r
+            RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]\r
             for Name,Value,Dummy,Arch,Platform,ID,LineNo in RecordList:\r
                 if Name == "IMAGE_ENTRY_POINT":\r
                     if self._ModuleEntryPointList == None:\r
@@ -1392,7 +1154,7 @@ class InfBuildData(ModuleBuildClassObject):
                 else:\r
                     ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)\r
                     if len(ToolList) == 0 or len(ToolList) != 1:\r
-                        EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,\r
+                        EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name, \r
                                        File=self.DescFilePath, Line=LineNo)\r
                     else:\r
                         if self._BuildOptions == None:\r
@@ -1409,7 +1171,6 @@ class InfBuildData(ModuleBuildClassObject):
                         else:\r
                             OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
                             self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value\r
-\r
         self._Header_ = 'DUMMY'\r
 \r
     def _GetInfVersion(self):\r
@@ -1533,11 +1294,11 @@ class InfBuildData(ModuleBuildClassObject):
             if self._DestructorList == None:\r
                 self._DestructorList = []\r
         return self._DestructorList\r
-\r
+                        \r
     def _GetBinaryFiles(self):\r
         if self._Binaries == None:\r
             self._Binaries = []\r
-            RecordList = self._Table.Query(MODEL_EFI_BINARY_FILE, Arch=self._Arch, Platform=self._Platform)\r
+            RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 FileType = Record[0]\r
                 File = NormPath(Record[1], self._Macros)\r
@@ -1553,7 +1314,7 @@ class InfBuildData(ModuleBuildClassObject):
     def _GetSourceFiles(self):\r
         if self._Sources == None:\r
             self._Sources = []\r
-            RecordList = self._Table.Query(MODEL_EFI_SOURCE_FILE, Arch=self._Arch, Platform=self._Platform)\r
+            RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 File = NormPath(Record[0], self._Macros)\r
                 LineNo = Record[-1]\r
@@ -1570,7 +1331,7 @@ class InfBuildData(ModuleBuildClassObject):
     def _GetLibraryClassUses(self):\r
         if self._LibraryClasses == None:\r
             self._LibraryClasses = sdict()\r
-            RecordList = self._Table.Query(MODEL_EFI_LIBRARY_CLASS, Arch=self._Arch, Platform=self._Platform)\r
+            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 Lib = Record[0]\r
                 Instance = Record[1]\r
@@ -1585,7 +1346,7 @@ class InfBuildData(ModuleBuildClassObject):
     def _GetLibraryNames(self):\r
         if self._Libraries == None:\r
             self._Libraries = []\r
-            RecordList = self._Table.Query(MODEL_EFI_LIBRARY_INSTANCE, Arch=self._Arch, Platform=self._Platform)\r
+            RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 # in case of name with '.lib' extension, which is unusual in R8.x inf\r
                 LibraryName = os.path.splitext(Record[0])[0]\r
@@ -1596,7 +1357,7 @@ class InfBuildData(ModuleBuildClassObject):
     def _GetProtocols(self):\r
         if self._Protocols == None:\r
             self._Protocols = sdict()\r
-            RecordList = self._Table.Query(MODEL_EFI_PROTOCOL, Arch=self._Arch, Platform=self._Platform)\r
+            RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 CName = Record[0]\r
                 Value = GuidValue(CName, self.Packages)\r
@@ -1610,7 +1371,7 @@ class InfBuildData(ModuleBuildClassObject):
     def _GetPpis(self):\r
         if self._Ppis == None:\r
             self._Ppis = sdict()\r
-            RecordList = self._Table.Query(MODEL_EFI_PPI, Arch=self._Arch, Platform=self._Platform)\r
+            RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 CName = Record[0]\r
                 Value = GuidValue(CName, self.Packages)\r
@@ -1624,7 +1385,7 @@ class InfBuildData(ModuleBuildClassObject):
     def _GetGuids(self):\r
         if self._Guids == None:\r
             self._Guids = sdict()\r
-            RecordList = self._Table.Query(MODEL_EFI_GUID, Arch=self._Arch, Platform=self._Platform)\r
+            RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 CName = Record[0]\r
                 Value = GuidValue(CName, self.Packages)\r
@@ -1638,7 +1399,7 @@ class InfBuildData(ModuleBuildClassObject):
     def _GetIncludes(self):\r
         if self._Includes == None:\r
             self._Includes = []\r
-            RecordList = self._Table.Query(MODEL_EFI_INCLUDE, Arch=self._Arch, Platform=self._Platform)\r
+            RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]\r
             # [includes] section must be used only in old (R8.x) inf file\r
             if self.AutoGenVersion >= 0x00010005 and len(RecordList) > 0:\r
                 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, "No [include] section allowed",\r
@@ -1662,14 +1423,14 @@ class InfBuildData(ModuleBuildClassObject):
     def _GetPackages(self):\r
         if self._Packages == None:\r
             self._Packages = []\r
-            RecordList = self._Table.Query(MODEL_META_DATA_PACKAGE, Arch=self._Arch, Platform=self._Platform)\r
+            RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 File = NormPath(Record[0], self._Macros)\r
                 LineNo = Record[-1]\r
                 if not ValidFile(File):\r
                     EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
                                     File=self.DescFilePath, Line=LineNo)\r
-                Package = self._Db.BuildObject[File, MODEL_FILE_DEC, self._Arch]\r
+                Package = self._Bdb[File, self._Arch]\r
                 self._Packages.append(Package)\r
         return self._Packages\r
 \r
@@ -1686,7 +1447,7 @@ class InfBuildData(ModuleBuildClassObject):
     def _GetBuildOptions(self):\r
         if self._BuildOptions == None:\r
             self._BuildOptions = sdict()\r
-            RecordList = self._Table.Query(MODEL_META_DATA_BUILD_OPTION, Arch=self._Arch, Platform=self._Platform)\r
+            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 ToolChainFamily = Record[0]\r
                 ToolChain = Record[1]\r
@@ -1700,19 +1461,29 @@ class InfBuildData(ModuleBuildClassObject):
 \r
     def _GetDepex(self):\r
         if self._Depex == None:\r
-            self._Depex = ''\r
-            RecordList = self._Table.Query(MODEL_EFI_DEPEX, Arch=self._Arch, Platform=self._Platform)\r
+            self._Depex = []\r
+            RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch, self._Platform]\r
             for Record in RecordList:\r
-                self._Depex += ' ' + Record[0]\r
+                TokenList = Record[0].split()\r
+                for Token in TokenList:\r
+                    if Token in DEPEX_SUPPORTED_OPCODE or Token.endswith(".inf"):\r
+                        self._Depex.append(Token)\r
+                    else:\r
+                        Value = GuidValue(Token, self.Packages)\r
+                        if Value == None:\r
+                            PackageList = '\t' + "\n\t".join([str(P)