Add part of build report generation features: PCD, Library, DEPEX, etc. (The build...
authorqhuang8 <qhuang8@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 11 Jan 2010 07:32:43 +0000 (07:32 +0000)
committerqhuang8 <qhuang8@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 11 Jan 2010 07:32:43 +0000 (07:32 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1799 7335b38e-4728-0410-8992-fb3ffe349368

Source/Python/AutoGen/AutoGen.py
Source/Python/build/BuildReport.py [new file with mode: 0755]
Source/Python/build/build.py

index ba026a9..cd9ecdc 100755 (executable)
-## @file
-# Generate AutoGen.h, AutoGen.c and *.depex files
-#
-# Copyright (c) 2007 - 2009, Intel Corporation
-# All rights reserved. This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution.  The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-
-## Import Modules
-#
-import os
-import re
-import os.path as path
-import copy
-
-import GenC
-import GenMake
-import GenDepex
-from StringIO import StringIO
-
-from StrGather import *
-from BuildEngine import BuildRule
-
-from Common.BuildToolError import *
-from Common.DataType import *
-from Common.Misc import *
-from Common.String import *
-import Common.GlobalData as GlobalData
-from GenFds.FdfParser import *
-from CommonDataClass.CommonClass import SkuInfoClass
-from Workspace.BuildClassObject import *
-
-## Regular expression for splitting Dependency Expression stirng into tokens
-gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")
-
-## Mapping Makefile type
-gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}
-
-
-## Build rule configuration file
-gBuildRuleFile = 'Conf/build_rule.txt'
-
-## default file name for AutoGen
-gAutoGenCodeFileName = "AutoGen.c"
-gAutoGenHeaderFileName = "AutoGen.h"
-gAutoGenStringFileName = "%(module_name)sStrDefs.h"
-gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk"
-gAutoGenDepexFileName = "%(module_name)s.depex"
-
-## Base class for AutoGen
-#
-#   This class just implements the cache mechanism of AutoGen objects.
-#
-class AutoGen(object):
-    # database to maintain the objects of xxxAutoGen
-    _CACHE_ = {}    # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}
-
-    ## Factory method
-    #
-    #   @param  Class           class object of real AutoGen class
-    #                           (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
-    #   @param  Workspace       Workspace directory or WorkspaceAutoGen object
-    #   @param  MetaFile        The path of meta file
-    #   @param  Target          Build target
-    #   @param  Toolchain       Tool chain name
-    #   @param  Arch            Target arch
-    #   @param  *args           The specific class related parameters
-    #   @param  **kwargs        The specific class related dict parameters
-    #
-    def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):
-        # check if the object has been created
-        Key = (Target, Toolchain)
-        if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \
-           or MetaFile not in Class._CACHE_[Key][Arch]:
-            AutoGenObject = super(AutoGen, Class).__new__(Class)
-            # call real constructor
-            if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):
-                return None
-            if Key not in Class._CACHE_:
-                Class._CACHE_[Key] = {}
-            if Arch not in Class._CACHE_[Key]:
-                Class._CACHE_[Key][Arch] = {}
-            Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject
-        else:
-            AutoGenObject = Class._CACHE_[Key][Arch][MetaFile]
-
-        return AutoGenObject
-
-    ## hash() operator
-    #
-    #  The file path of platform file will be used to represent hash value of this object
-    #
-    #   @retval int     Hash value of the file path of platform file
-    #
-    def __hash__(self):
-        return hash(self.MetaFile)
-
-    ## str() operator
-    #
-    #  The file path of platform file will be used to represent this object
-    #
-    #   @retval string  String of platform file path
-    #
-    def __str__(self):
-        return str(self.MetaFile)
-
-    ## "==" operator
-    def __eq__(self, Other):
-        return Other and self.MetaFile == Other
-
-## Workspace AutoGen class
-#
-#   This class is used mainly to control the whole platform build for different
-# architecture. This class will generate top level makefile.
-#
-class WorkspaceAutoGen(AutoGen):
-    ## Real constructor of WorkspaceAutoGen
-    #
-    # This method behaves the same as __init__ except that it needs explict invoke
-    # (in super class's __new__ method)
-    #
-    #   @param  WorkspaceDir            Root directory of workspace
-    #   @param  ActivePlatform          Meta-file of active platform
-    #   @param  Target                  Build target
-    #   @param  Toolchain               Tool chain name
-    #   @param  ArchList                List of architecture of current build
-    #   @param  MetaFileDb              Database containing meta-files
-    #   @param  BuildConfig             Configuration of build
-    #   @param  ToolDefinition          Tool chain definitions
-    #   @param  FlashDefinitionFile     File of flash definition
-    #   @param  Fds                     FD list to be generated
-    #   @param  Fvs                     FV list to be generated
-    #   @param  SkuId                   SKU id from command line
-    #
-    def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,
-              BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=[], Fvs=[], SkuId='', 
-              ReportFile=None, ReportType=None):
-        self.MetaFile       = ActivePlatform.MetaFile
-        self.WorkspaceDir   = WorkspaceDir
-        self.Platform       = ActivePlatform
-        self.BuildTarget    = Target
-        self.ToolChain      = Toolchain
-        self.ArchList       = ArchList
-        self.SkuId          = SkuId
-        self.ReportFile     = ReportFile
-        self.ReportType     = ReportType
-
-        self.BuildDatabase  = MetaFileDb
-        self.TargetTxt      = BuildConfig
-        self.ToolDef        = ToolDefinition
-        self.FdfFile        = FlashDefinitionFile
-        self.FdTargetList   = Fds
-        self.FvTargetList   = Fvs
-        self.AutoGenObjectList = []
-
-        # there's many relative directory operations, so ...
-        os.chdir(self.WorkspaceDir)
-
-        # parse FDF file to get PCDs in it, if any
-        if self.FdfFile != None and self.FdfFile != '':
-            Fdf = FdfParser(self.FdfFile.Path)
-            Fdf.ParseFile()
-            PcdSet = Fdf.Profile.PcdDict
-            ModuleList = Fdf.Profile.InfList
-        else:
-            PcdSet = {}
-            ModuleList = []
-
-        # apply SKU and inject PCDs from Flash Definition file
-        for Arch in self.ArchList:
-            Platform = self.BuildDatabase[self.MetaFile, Arch]
-            Platform.SkuName = self.SkuId
-            for Name, Guid in PcdSet:
-                Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])
-
-            Pa = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
-            #
-            # Explicitly collect platform's dynamic PCDs
-            #
-            Pa.CollectPlatformDynamicPcds()
-            self.AutoGenObjectList.append(Pa)
-
-        AllPcds = {}
-        MaxLen = 0
-        for Pcd in Pa._DynaPcdList_ + Pa._NonDynaPcdList_:
-          if Pcd.TokenSpaceGuidCName not in AllPcds:
-            AllPcds[Pcd.TokenSpaceGuidCName] = {}
-          if Pcd.Type not in AllPcds[Pcd.TokenSpaceGuidCName]:
-            AllPcds[Pcd.TokenSpaceGuidCName][Pcd.Type] = []
-          AllPcds[Pcd.TokenSpaceGuidCName][Pcd.Type] += [Pcd]
-          if len(Pcd.TokenCName) > MaxLen:
-            MaxLen = len(Pcd.TokenCName)
-
-        if self.ReportFile <> None:
-          try:
-            if os.path.exists(self.ReportFile):
-              os.remove(self.ReportFile)
-
-            Fd = open(self.ReportFile, "w")
-       
-            Fd.write ('===============================================================================\n')
-            Fd.write ('Platform Configuration Database Report\n')
-            Fd.write ('===============================================================================\n')
-            Fd.write ('  *P  - Platform scoped PCD override in DSC file\n')
-            Fd.write ('  *F  - Platform scoped PCD override in FDF file\n')
-            Fd.write ('  *M  - Module scoped PCD override in DSC file\n')
-            Fd.write ('  *C  - Library has a constructor\n')
-            Fd.write ('  *D  - Library has a destructor\n')
-            Fd.write ('  *CD - Library has both a constructor and a destructor\n')
-            Fd.write ('===============================================================================\n')
-            Fd.write ('\n')
-            Fd.write ('===============================================================================\n')
-            Fd.write ('PLATFORM: %s\n' % (ActivePlatform.MetaFile))
-            Fd.write ('===============================================================================\n')
-            for Key in AllPcds:
-              Fd.write ('%s\n' % (Key))
-              for Type in AllPcds[Key]:
-                TypeName = ''
-                DecType = Type
-                if Type == 'FixedAtBuild':
-                  TypeName = 'FIXED'
-                if Type == 'PatchableInModule':
-                  TypeName = 'PATCH'
-                if Type == 'FeatureFlag':
-                  TypeName = 'FLAG'
-                if Type == 'Dynamic':
-                  TypeName = 'DYN'
-                if Type == 'DynamicHii':
-                  TypeName = 'DYNHII'
-                  DecType = 'Dynamic'
-                if Type == 'DynamicVpd':
-                  TypeName = 'DYNVPD'
-                  DecType = 'Dynamic'
-                if Type == 'DynamicEx':
-                  TypeName = 'DEX'
-                  DecType = 'Dynamic'
-                if Type == 'DynamicExHii':
-                  TypeName = 'DEXHII'
-                  DecType = 'Dynamic'
-                if Type == 'DynamicExVpd':
-                  TypeName = 'DEXVPD'
-                  DecType = 'Dynamic'
-                for Pcd in AllPcds[Key][Type]:
-                
-                  DecDefaultValue = None
-                  for F in Pa.Platform.Modules.keys():
-                    for Package in Pa.Platform.Modules[F].M.Module.Packages:
-                      if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType) in Package.Pcds:
-                        if DecDefaultValue == None:
-                          DecDefaultValue = Package.Pcds[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType].DefaultValue
-
-                  DscDefaultValue = None
-                  if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in self.BuildDatabase.WorkspaceDb.PlatformList[0].Pcds:
-                    DscDefaultValue = self.BuildDatabase.WorkspaceDb.PlatformList[0].Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)].DefaultValue
-
-                  if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
-                    if Pcd.DefaultValue.strip()[0:2].upper() == '0X':
-                      PcdDefaultValueNumber = int(Pcd.DefaultValue.strip(), 16)
-                    else:
-                      PcdDefaultValueNumber = int(Pcd.DefaultValue.strip())
-                  
-                    if DecDefaultValue == None:
-                      DecMatch = True
-                    else:
-                      if DecDefaultValue.strip()[0:2].upper() == '0X':
-                        DecDefaultValueNumber = int(DecDefaultValue.strip(), 16)
-                      else:
-                        DecDefaultValueNumber = int(DecDefaultValue.strip())
-                      DecMatch = (DecDefaultValueNumber == PcdDefaultValueNumber)
-                      
-                    if DscDefaultValue == None:
-                      DscMatch = True
-                    else:
-                      if DscDefaultValue.strip()[0:2].upper() == '0X':
-                        DscDefaultValueNumber = int(DscDefaultValue.strip(), 16)
-                      else:
-                        DscDefaultValueNumber = int(DscDefaultValue.strip())
-                      DscMatch = (DscDefaultValueNumber == PcdDefaultValueNumber)
-                  else:
-                    if DecDefaultValue == None:
-                      DecMatch = True
-                    else:
-                      DecMatch = (DecDefaultValue == Pcd.DefaultValue)
-                      
-                    if DscDefaultValue == None:
-                      DscMatch = True
-                    else:
-                      DscMatch = (DscDefaultValue == Pcd.DefaultValue)
-     
-                  if DecMatch:
-                    Fd.write ('    %-*s: %6s %10s = %-22s\n' % (MaxLen + 2, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', Pcd.DefaultValue))
-                  else:
-                    if DscMatch:
-                      if (Pcd.TokenCName, Key) in PcdSet:
-                        Fd.write (' *F %-*s: %6s %10s = %-22s\n' % (MaxLen + 2, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', Pcd.DefaultValue))
-                      else:
-                        Fd.write (' *P %-*s: %6s %10s = %-22s\n' % (MaxLen + 2, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', Pcd.DefaultValue))
-
-                  for F in Pa.Platform.Modules.keys():
-                    for ModulePcd in Pa.Platform.Modules[F].M.ModulePcdList + Pa.Platform.Modules[F].M.LibraryPcdList:
-                      if ModulePcd.TokenSpaceGuidCName <> Pcd.TokenSpaceGuidCName:
-                        continue
-                      if ModulePcd.TokenCName <> Pcd.TokenCName:
-                        continue
-                      if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
-                        if ModulePcd.DefaultValue.strip()[0:2].upper() == '0X':
-                          ModulePcdDefaultValueNumber = int(ModulePcd.DefaultValue.strip(), 16)
-                        else:
-                          ModulePcdDefaultValueNumber = int(ModulePcd.DefaultValue.strip())
-                        Match = (ModulePcdDefaultValueNumber == PcdDefaultValueNumber)
-                      else:
-                        Match = (ModulePcd.DefaultValue == Pcd.DefaultValue)
-                      if Match:
-                        continue
-                      Fd.write (' *M %*s = %s\n' % (MaxLen + 21, str(F).split('\\')[-1], ModulePcd.DefaultValue))
-                      
-                  if not DecMatch and DscMatch and DecDefaultValue <> None:
-                    Fd.write ('    %*s = %s\n' % (MaxLen + 21, 'DEC DEFAULT', DecDefaultValue))
-                      
-              Fd.write ('\n')
-
-            Fd.write ('===============================================================================\n')
-            Fd.write ('===============================================================================\n')
-            
-            for F in Pa.Platform.Modules.keys():
-              Fd.write ('\n')
-              Fd.write ('===============================================================================\n')
-              Fd.write ('MODULE: %s\n' % (F))
-              Fd.write ('===============================================================================\n')
-              
-              Fd.write ('PLATFORM CONFIGURATION DATABASE\n')
-              Fd.write ('-------------------------------------------------------------------------------\n')
-              ModuleFirst = True
-              for Key in AllPcds:
-                First = True
-                for Type in AllPcds[Key]:
-                  TypeName = ''
-                  DecType = Type
-                  if Type == 'FixedAtBuild':
-                    TypeName = 'FIXED'
-                  if Type == 'PatchableInModule':
-                    TypeName = 'PATCH'
-                  if Type == 'FeatureFlag':
-                    TypeName = 'FLAG'
-                  if Type == 'Dynamic':
-                    TypeName = 'DYN'
-                  if Type == 'DynamicHii':
-                    TypeName = 'DYNHII'
-                    DecType = 'Dynamic'
-                  if Type == 'DynamicVpd':
-                    TypeName = 'DYNVPD'
-                    DecType = 'Dynamic'
-                  if Type == 'DynamicEx':
-                    TypeName = 'DEX'
-                    DecType = 'Dynamic'
-                  if Type == 'DynamicExHii':
-                    TypeName = 'DEXHII'
-                    DecType = 'Dynamic'
-                  if Type == 'DynamicExVpd':
-                    TypeName = 'DEXVPD'
-                    DecType = 'Dynamic'
-                  for Pcd in AllPcds[Key][Type]:
-                    for ModulePcd in Pa.Platform.Modules[F].M.ModulePcdList + Pa.Platform.Modules[F].M.LibraryPcdList:
-                      if ModulePcd.TokenSpaceGuidCName <> Pcd.TokenSpaceGuidCName:
-                        continue
-                      if ModulePcd.TokenCName <> Pcd.TokenCName:
-                        continue
-                      if ModulePcd.Type <> Pcd.Type:
-                        continue
-                      if First:
-                        if ModuleFirst:
-                          ModuleFirst = False
-                        else:
-                          Fd.write ('\n')
-                        Fd.write ('%s\n' % (Key))
-                        First = False
-
-                      InfDefaultValue = ModulePcd.InfDefaultValue
-                      if InfDefaultValue == '':
-                        InfDefaultValue = None
-
-                      DecDefaultValue = None
-                      for Package in Pa.Platform.Modules[F].M.Module.Packages:
-                        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType) in Package.Pcds:
-                          if DecDefaultValue == None:
-                            DecDefaultValue = Package.Pcds[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType].DefaultValue
-
-                      DscDefaultValue = None
-                      if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in self.BuildDatabase.WorkspaceDb.PlatformList[0].Pcds:
-                        DscDefaultValue = self.BuildDatabase.WorkspaceDb.PlatformList[0].Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)].DefaultValue
-
-                      DscModuleOverrideDefaultValue = None
-                      if F in self.BuildDatabase.WorkspaceDb.PlatformList[0].Modules:
-                        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in self.BuildDatabase.WorkspaceDb.PlatformList[0].Modules[F].Pcds:
-                          DscModuleOverrideDefaultValue = self.BuildDatabase.WorkspaceDb.PlatformList[0].Modules[F].Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)].DefaultValue
-                      
-                      if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
-                        if ModulePcd.DefaultValue.strip()[0:2].upper() == '0X':
-                          ModulePcdDefaultValueNumber = int(ModulePcd.DefaultValue.strip(), 16)
-                        else:
-                          ModulePcdDefaultValueNumber = int(ModulePcd.DefaultValue.strip())
-                          
-                        if DecDefaultValue == None:
-                          DecMatch = True
-                        else:
-                          if DecDefaultValue.strip()[0:2].upper() == '0X':
-                            DecDefaultValueNumber = int(DecDefaultValue.strip(), 16)
-                          else:
-                            DecDefaultValueNumber = int(DecDefaultValue.strip())
-                          DecMatch = (DecDefaultValueNumber == ModulePcdDefaultValueNumber)
-                          
-                        if InfDefaultValue == None:
-                          InfMatch = True
-                        else:
-                          if InfDefaultValue.strip()[0:2].upper() == '0X':
-                            InfDefaultValueNumber = int(InfDefaultValue.strip(), 16)
-                          else:
-                            InfDefaultValueNumber = int(InfDefaultValue.strip())
-                          InfMatch = (InfDefaultValueNumber == ModulePcdDefaultValueNumber)
-
-                        if DscDefaultValue == None:
-                          DscMatch = True
-                        else:
-                          if DscDefaultValue.strip()[0:2].upper() == '0X':
-                            DscDefaultValueNumber = int(DscDefaultValue.strip(), 16)
-                          else:
-                            DscDefaultValueNumber = int(DscDefaultValue.strip())
-                          DscMatch = (DscDefaultValueNumber == ModulePcdDefaultValueNumber)
-                      else:
-                        if DecDefaultValue == None:
-                          DecMatch = True
-                        else:
-                          DecMatch = (DecDefaultValue == ModulePcd.DefaultValue)
-                          
-                        if InfDefaultValue == None:
-                          InfMatch = True
-                        else:
-                          InfMatch = (InfDefaultValue == ModulePcd.DefaultValue)
-                          
-                        if DscDefaultValue == None:
-                          DscMatch = True
-                        else:
-                          DscMatch = (DscDefaultValue == ModulePcd.DefaultValue)
-                          
-                      if DecMatch and InfMatch:
-                        Fd.write ('    %-*s: %6s %10s = %-22s\n' % (MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', ModulePcd.DefaultValue))
-                      else:
-                        if DscMatch and DscModuleOverrideDefaultValue == None:
-                          if (Pcd.TokenCName, Key) in PcdSet:
-                            Fd.write (' *F %-*s: %6s %10s = %-22s\n' % (MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', ModulePcd.DefaultValue))
-                          else:
-                            Fd.write (' *P %-*s: %6s %10s = %-22s\n' % (MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', ModulePcd.DefaultValue))
-                        else:
-                          Fd.write (' *M %-*s: %6s %10s = %-22s\n' % (MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', ModulePcd.DefaultValue))
-                          if DscDefaultValue <> None:
-                            Fd.write ('    %*s = %s\n' % (MaxLen + 19, 'DSC DEFAULT', DscDefaultValue))
-                        if InfDefaultValue <> None:
-                          Fd.write ('    %*s = %s\n' % (MaxLen + 19, 'INF DEFAULT', InfDefaultValue))
-                        if DecDefaultValue <> None and not DecMatch:
-                          Fd.write ('    %*s = %s\n' % (MaxLen + 19, 'DEC DEFAULT', DecDefaultValue))
-              Fd.write ('-------------------------------------------------------------------------------\n')
-              Fd.write ('LIBRARIES\n')
-              Fd.write ('-------------------------------------------------------------------------------\n')
-              for Lib in Pa.Platform.Modules[F].M.DependentLibraryList:
-                if len(Lib.ConstructorList) > 0:
-                  if  len(Lib.DestructorList) > 0:
-                    Fd.write (' *CD')
-                  else:
-                    Fd.write (' *C ')
-                else:
-                  if  len(Lib.DestructorList) > 0:
-                    Fd.write (' *D ')
-                  else:
-                    Fd.write ('    ')
-                Fd.write (' %s\n' % (Lib))
-                for Depex in Lib.DepexExpression[Pa.Platform.Modules[F].M.Arch, Pa.Platform.Modules[F].M.ModuleType]:
-                  Fd.write ('       DEPEX = %s\n' % (Depex))
-              Fd.write ('-------------------------------------------------------------------------------\n')
-
-              Fd.write ('MODULE DEPENDENCY EXPRESSION\n')
-              if len(Pa.Platform.Modules[F].M.Module.DepexExpression[Pa.Platform.Modules[F].M.Arch, Pa.Platform.Modules[F].M.ModuleType]) == 0:
-                Fd.write ('  NONE\n')
-              else:
-                for Depex in Pa.Platform.Modules[F].M.Module.DepexExpression[Pa.Platform.Modules[F].M.Arch, Pa.Platform.Modules[F].M.ModuleType]:
-                  Fd.write ('  %s\n' % (Depex))
-              Fd.write ('-------------------------------------------------------------------------------\n')
-
-              Fd.write ('MODULE + LIBRARY DEPENDENCY EXPRESSION\n')
-              if Pa.Platform.Modules[F].M.ModuleType in Pa.Platform.Modules[F].M.DepexExpressionList:
-                if Pa.Platform.Modules[F].M.DepexExpressionList[Pa.Platform.Modules[F].M.ModuleType] == '': 
-                  Fd.write ('  NONE\n')
-                else:
-                  Fd.write ('  %s\n' % (Pa.Platform.Modules[F].M.DepexExpressionList[Pa.Platform.Modules[F].M.ModuleType]))
-              else:
-                Fd.write ('  NONE\n')
-              Fd.write ('-------------------------------------------------------------------------------\n')
-              
-            Fd.close()
-          except:
-            EdkLogger.error(None, FILE_OPEN_FAILURE, ExtraData=self.ReportFile)
-                  
-        self._BuildDir = None
-        self._FvDir = None
-        self._MakeFileDir = None
-        self._BuildCommand = None
-
-        return True
-
-    def __repr__(self):
-        return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList))
-
-    ## Return the directory to store FV files
-    def _GetFvDir(self):
-        if self._FvDir == None:
-            self._FvDir = path.join(self.BuildDir, 'FV')
-        return self._FvDir
-
-    ## Return the directory to store all intermediate and final files built
-    def _GetBuildDir(self):
-        return self.AutoGenObjectList[0].BuildDir
-
-    ## Return the build output directory platform specifies
-    def _GetOutputDir(self):
-        return self.Platform.OutputDirectory
-
-    ## Return platform name
-    def _GetName(self):
-        return self.Platform.PlatformName
-
-    ## Return meta-file GUID
-    def _GetGuid(self):
-        return self.Platform.Guid
-
-    ## Return platform version
-    def _GetVersion(self):
-        return self.Platform.Version
-
-    ## Return paths of tools
-    def _GetToolDefinition(self):
-        return self.AutoGenObjectList[0].ToolDefinition
-
-    ## Return directory of platform makefile
-    #
-    #   @retval     string  Makefile directory
-    #
-    def _GetMakeFileDir(self):
-        if self._MakeFileDir == None:
-            self._MakeFileDir = self.BuildDir
-        return self._MakeFileDir
-
-    ## Return build command string
-    #
-    #   @retval     string  Build command string
-    #
-    def _GetBuildCommand(self):
-        if self._BuildCommand == None:
-            # BuildCommand should be all the same. So just get one from platform AutoGen
-            self._BuildCommand = self.AutoGenObjectList[0].BuildCommand
-        return self._BuildCommand
-
-    ## Create makefile for the platform and mdoules in it
-    #
-    #   @param      CreateDepsMakeFile      Flag indicating if the makefile for
-    #                                       modules will be created as well
-    #
-    def CreateMakeFile(self, CreateDepsMakeFile=False):
-        # create makefile for platform
-        Makefile = GenMake.TopLevelMakefile(self)
-        if Makefile.Generate():
-            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for platform [%s] %s\n" %
-                            (self.MetaFile, self.ArchList))
-        else:
-            EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for platform [%s] %s\n" %
-                            (self.MetaFile, self.ArchList))
-
-        if CreateDepsMakeFile:
-            for Pa in self.AutoGenObjectList:
-                Pa.CreateMakeFile(CreateDepsMakeFile)
-
-    ## Create autogen code for platform and modules
-    #
-    #  Since there's no autogen code for platform, this method will do nothing
-    #  if CreateModuleCodeFile is set to False.
-    #
-    #   @param      CreateDepsCodeFile      Flag indicating if creating module's
-    #                                       autogen code file or not
-    #
-    def CreateCodeFile(self, CreateDepsCodeFile=False):
-        if not CreateDepsCodeFile:
-            return
-        for Pa in self.AutoGenObjectList:
-            Pa.CreateCodeFile(CreateDepsCodeFile)
-
-    Name                = property(_GetName)
-    Guid                = property(_GetGuid)
-    Version             = property(_GetVersion)
-    OutputDir           = property(_GetOutputDir)
-
-    ToolDefinition      = property(_GetToolDefinition)       # toolcode : tool path
-
-    BuildDir            = property(_GetBuildDir)
-    FvDir               = property(_GetFvDir)
-    MakeFileDir         = property(_GetMakeFileDir)
-    BuildCommand        = property(_GetBuildCommand)
-
-## AutoGen class for platform
-#
-#  PlatformAutoGen class will process the original information in platform
-#  file in order to generate makefile for platform.
-#
-class PlatformAutoGen(AutoGen):
-    #
-    # Used to store all PCDs for both PEI and DXE phase, in order to generate 
-    # correct PCD database
-    # 
-    _DynaPcdList_ = []
-    _NonDynaPcdList_ = []
-
-    ## The real constructor of PlatformAutoGen
-    #
-    #  This method is not supposed to be called by users of PlatformAutoGen. It's
-    #  only used by factory method __new__() to do real initialization work for an
-    #  object of PlatformAutoGen
-    #
-    #   @param      Workspace       WorkspaceAutoGen object
-    #   @param      PlatformFile    Platform file (DSC file)
-    #   @param      Target          Build target (DEBUG, RELEASE)
-    #   @param      Toolchain       Name of tool chain
-    #   @param      Arch            arch of the platform supports
-    #
-    def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):
-        EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch))
-        GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target)
-
-        self.MetaFile = PlatformFile
-        self.Workspace = Workspace
-        self.WorkspaceDir = Workspace.WorkspaceDir
-        self.ToolChain = Toolchain
-        self.BuildTarget = Target
-        self.Arch = Arch
-        self.SourceDir = PlatformFile.SubDir
-        self.SourceOverrideDir = None
-        self.FdTargetList = self.Workspace.FdTargetList
-        self.FvTargetList = self.Workspace.FvTargetList
-
-        # flag indicating if the makefile/C-code file has been created or not
-        self.IsMakeFileCreated  = False
-        self.IsCodeFileCreated  = False
-
-        self._Platform   = None
-        self._Name       = None
-        self._Guid       = None
-        self._Version    = None
-
-        self._BuildRule = None
-        self._SourceDir = None
-        self._BuildDir = None
-        self._OutputDir = None
-        self._FvDir = None
-        self._MakeFileDir = None
-        self._FdfFile = None
-
-        self._PcdTokenNumber = None    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
-        self._DynamicPcdList = None    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
-        self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
-
-        self._ToolDefinitions = None
-        self._ToolDefFile = None          # toolcode : tool path
-        self._ToolChainFamily = None
-        self._BuildRuleFamily = None
-        self._BuildOption = None          # toolcode : option
-        self._PackageList = None
-        self._ModuleAutoGenList  = None
-        self._LibraryAutoGenList = None
-        self._BuildCommand = None
-
-        # get the original module/package/platform objects
-        self.BuildDatabase = Workspace.BuildDatabase
-        return True
-
-    def __repr__(self):
-        return "%s [%s]" % (self.MetaFile, self.Arch)
-
-    ## Create autogen code for platform and modules
-    #
-    #  Since there's no autogen code for platform, this method will do nothing
-    #  if CreateModuleCodeFile is set to False.
-    #
-    #   @param      CreateModuleCodeFile    Flag indicating if creating module's
-    #                                       autogen code file or not
-    #
-    def CreateCodeFile(self, CreateModuleCodeFile=False):
-        # only module has code to be greated, so do nothing if CreateModuleCodeFile is False
-        if self.IsCodeFileCreated or not CreateModuleCodeFile:
-            return
-
-        for Ma in self.ModuleAutoGenList:
-            Ma.CreateCodeFile(True)
-
-        # don't do this twice
-        self.IsCodeFileCreated = True
-
-    ## Create makefile for the platform and mdoules in it
-    #
-    #   @param      CreateModuleMakeFile    Flag indicating if the makefile for
-    #                                       modules will be created as well
-    #
-    def CreateMakeFile(self, CreateModuleMakeFile=False):
-        if CreateModuleMakeFile:
-            for ModuleFile in self.Platform.Modules:
-                Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,
-                                   self.ToolChain, self.Arch, self.MetaFile)
-                Ma.CreateMakeFile(True)
-
-        # no need to create makefile for the platform more than once
-        if self.IsMakeFileCreated:
-            return
-
-        # create makefile for platform
-        Makefile = GenMake.PlatformMakefile(self)
-        if Makefile.Generate():
-            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for platform [%s] [%s]\n" %
-                            (self.MetaFile, self.Arch))
-        else:
-            EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for platform [%s] [%s]\n" %
-                            (self.MetaFile, self.Arch))
-        self.IsMakeFileCreated = True
-
-    ## Collect dynamic PCDs
-    #
-    #  Gather dynamic PCDs list from each module and their settings from platform
-    #  This interface should be invoked explicitly when platform action is created.
-    #
-    def CollectPlatformDynamicPcds(self):
-        # for gathering error information
-        NoDatumTypePcdList = set()
-
-        self._GuidValue = {}
-        for F in self.Platform.Modules.keys():
-            M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile)
-            #GuidValue.update(M.Guids)
-            
-            self.Platform.Modules[F].M = M
-            
-            for PcdFromModule in M.ModulePcdList+M.LibraryPcdList:
-                # make sure that the "VOID*" kind of datum has MaxDatumSize set
-                if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize == None:
-                    NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, F))
-
-                if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:
-                    #
-                    # If a dynamic PCD used by a PEM module/PEI module & DXE module,
-                    # it should be stored in Pcd PEI database, If a dynamic only
-                    # used by DXE module, it should be stored in DXE PCD database.
-                    # The default Phase is DXE
-                    #
-                    if M.ModuleType in ["PEIM", "PEI_CORE"]:
-                        PcdFromModule.Phase = "PEI"
-                    if PcdFromModule not in self._DynaPcdList_:
-                        self._DynaPcdList_.append(PcdFromModule)
-                    elif PcdFromModule.Phase == 'PEI':
-                        # overwrite any the same PCD existing, if Phase is PEI
-                        Index = self._DynaPcdList_.index(PcdFromModule)
-                        self._DynaPcdList_[Index] = PcdFromModule
-                elif PcdFromModule not in self._NonDynaPcdList_:
-                    self._NonDynaPcdList_.append(PcdFromModule)
-
-        # print out error information and break the build, if error found
-        if len(NoDatumTypePcdList) > 0:
-            NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)
-            EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",
-                            File=self.MetaFile,
-                            ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
-                                      % NoDatumTypePcdListString)
-        self._NonDynamicPcdList = self._NonDynaPcdList_
-        self._DynamicPcdList = self._DynaPcdList_
-        
-        #
-        # Sort dynamic PCD list to:
-        # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should 
-        #    try to be put header of dynamicd List
-        # 2) If PCD is HII type, the PCD item should be put after unicode type PCD
-        #
-        # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.
-        #
-        UnicodePcdArray = []
-        HiiPcdArray     = []
-        OtherPcdArray   = []
-        for Pcd in self._DynamicPcdList:
-            # just pick the a value to determine whether is unicode string type
-            Sku      = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]
-            PcdValue = Sku.DefaultValue
-            if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):
-                # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
-                UnicodePcdArray.append(Pcd)
-            elif len(Sku.VariableName) > 0:
-                # if found HII type PCD then insert to right of UnicodeIndex
-                HiiPcdArray.append(Pcd)
-            else:
-                OtherPcdArray.append(Pcd)
-        del self._DynamicPcdList[:]
-        self._DynamicPcdList.extend(UnicodePcdArray)
-        self._DynamicPcdList.extend(HiiPcdArray)
-        self._DynamicPcdList.extend(OtherPcdArray)
-            
-        
-    ## Return the platform build data object
-    def _GetPlatform(self):
-        if self._Platform == None:
-            self._Platform = self.BuildDatabase[self.MetaFile, self.Arch]
-        return self._Platform
-
-    ## Return platform name
-    def _GetName(self):
-        return self.Platform.PlatformName
-
-    ## Return the meta file GUID
-    def _GetGuid(self):
-        return self.Platform.Guid
-
-    ## Return the platform version
-    def _GetVersion(self):
-        return self.Platform.Version
-
-    ## Return the FDF file name
-    def _GetFdfFile(self):
-        if self._FdfFile == None:
-            if self.Workspace.FdfFile != "":
-                self._FdfFile= path.join(self.WorkspaceDir, self.Workspace.FdfFile)
-            else:
-                self._FdfFile = ''
-        return self._FdfFile
-
-    ## Return the build output directory platform specifies
-    def _GetOutputDir(self):
-        return self.Platform.OutputDirectory
-
-    ## Return the directory to store all intermediate and final files built
-    def _GetBuildDir(self):
-        if self._BuildDir == None:
-            if os.path.isabs(self.OutputDir):
-                self._BuildDir = path.join(
-                                            path.abspath(self.OutputDir),
-                                            self.BuildTarget + "_" + self.ToolChain,
-                                            )
-            else:
-                self._BuildDir = path.join(
-                                            self.WorkspaceDir,
-                                            self.OutputDir,
-                                            self.BuildTarget + "_" + self.ToolChain,
-                                            )
-        return self._BuildDir
-
-    ## Return directory of platform makefile
-    #
-    #   @retval     string  Makefile directory
-    #
-    def _GetMakeFileDir(self):
-        if self._MakeFileDir == None:
-            self._MakeFileDir = path.join(self.BuildDir, self.Arch)
-        return self._MakeFileDir
-
-    ## Return build command string
-    #
-    #   @retval     string  Build command string
-    #
-    def _GetBuildCommand(self):
-        if self._BuildCommand == None:
-            self._BuildCommand = []
-            if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:
-                self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"])
-                if "FLAGS" in self.ToolDefinition["MAKE"]:
-                    NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip()
-                    if NewOption != '':
-                      self._BuildCommand += SplitOption(NewOption)
-        return self._BuildCommand
-
-    ## Get tool chain definition
-    #
-    #  Get each tool defition for given tool chain from tools_def.txt and platform
-    #
-    def _GetToolDefinition(self):
-        if self._ToolDefinitions == None:
-            ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary
-            if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase:
-                EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration",
-                                ExtraData="[%s]" % self.MetaFile)
-            self._ToolDefinitions = {}
-            DllPathList = set()
-            for Def in ToolDefinition:
-                Target, Tag, Arch, Tool, Attr = Def.split("_")
-                if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:
-                    continue
-
-                Value = ToolDefinition[Def]
-                # don't record the DLL
-                if Attr == "DLL":
-                    DllPathList.add(Value)
-                    continue
-
-                if Tool not in self._ToolDefinitions:
-                    self._ToolDefinitions[Tool] = {}
-                self._ToolDefinitions[Tool][Attr] = Value
-
-            ToolsDef = ''
-            MakePath = ''
-            if GlobalData.gOptions.SilentMode and "MAKE" in self._ToolDefinitions:
-                if "FLAGS" not in self._ToolDefinitions["MAKE"]:
-                    self._ToolDefinitions["MAKE"]["FLAGS"] = ""
-                self._ToolDefinitions["MAKE"]["FLAGS"] += " -s"
-            MakeFlags = ''
-            for Tool in self._ToolDefinitions:
-                for Attr in self._ToolDefinitions[Tool]:
-                    Value = self._ToolDefinitions[Tool][Attr]
-                    if Tool in self.BuildOption and Attr in self.BuildOption[Tool]:
-                        # check if override is indicated
-                        if self.BuildOption[Tool][Attr].startswith('='):
-                            Value = self.BuildOption[Tool][Attr][1:]
-                        else:
-                            Value += " " + self.BuildOption[Tool][Attr]
-
-                    if Attr == "PATH":
-                        # Don't put MAKE definition in the file
-                        if Tool == "MAKE":
-                            MakePath = Value
-                        else:
-                            ToolsDef += "%s = %s\n" % (Tool, Value)
-                    elif Attr != "DLL":
-                        # Don't put MAKE definition in the file
-                        if Tool == "MAKE":
-                            if Attr == "FLAGS":
-                                MakeFlags = Value
-                        else:
-                            ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)
-                ToolsDef += "\n"
-
-            SaveFileOnChange(self.ToolDefinitionFile, ToolsDef)
-            for DllPath in DllPathList:
-                os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"]
-            os.environ["MAKE_FLAGS"] = MakeFlags
-
-        return self._ToolDefinitions
-
-    ## Return the paths of tools
-    def _GetToolDefFile(self):
-        if self._ToolDefFile == None:
-            self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch)
-        return self._ToolDefFile
-
-    ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.
-    def _GetToolChainFamily(self):
-        if self._ToolChainFamily == None:
-            ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase
-            if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
-               or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
-               or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]:
-                EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
-                                   % self.ToolChain)
-                self._ToolChainFamily = "MSFT"
-            else:
-                self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]
-        return self._ToolChainFamily
-
-    def _GetBuildRuleFamily(self):
-        if self._BuildRuleFamily == None:
-            ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase
-            if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \
-               or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \
-               or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]:
-                EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
-                                   % self.ToolChain)
-                self._BuildRuleFamily = "MSFT"
-            else:
-                self._BuildRuleFamily = ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]
-        return self._BuildRuleFamily
-
-    ## Return the build options specific to this platform
-    def _GetBuildOptions(self):
-        if self._BuildOption == None:
-            self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)
-        return self._BuildOption
-
-    ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt
-    #
-    #   @retval     BuildRule object
-    #
-    def _GetBuildRule(self):
-        if self._BuildRule == None:
-            BuildRuleFile = None
-            if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary:
-                BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]
-            if BuildRuleFile in [None, '']:
-                BuildRuleFile = gBuildRuleFile
-            self._BuildRule = BuildRule(BuildRuleFile)
-        return self._BuildRule
-
-    ## Summarize the packages used by modules in this platform
-    def _GetPackageList(self):
-        if self._PackageList == None:
-            self._PackageList = set()
-            for La in self.LibraryAutoGenList:
-                self._PackageList.update(La.DependentPackageList)
-            for Ma in self.ModuleAutoGenList:
-                self._PackageList.update(Ma.DependentPackageList)
-            self._PackageList = list(self._PackageList)
-        return self._PackageList
-
-    ## Get list of non-dynamic PCDs
-    def _GetNonDynamicPcdList(self):
-        return self._NonDynamicPcdList
-
-    ## Get list of dynamic PCDs
-    def _GetDynamicPcdList(self):
-        return self._DynamicPcdList
-
-    ## Generate Token Number for all PCD
-    def _GetPcdTokenNumbers(self):
-        if self._PcdTokenNumber == None:
-            self._PcdTokenNumber = sdict()
-            TokenNumber = 1
-            for Pcd in self.DynamicPcdList:
-                if Pcd.Phase == "PEI":
-                    EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
-                    self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
-                    TokenNumber += 1
-
-            for Pcd in self.DynamicPcdList:
-                if Pcd.Phase == "DXE":
-                    EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
-                    self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
-                    TokenNumber += 1
-
-            for Pcd in self.NonDynamicPcdList:
-                self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
-                TokenNumber += 1
-        return self._PcdTokenNumber
-
-    ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform
-    def _GetAutoGenObjectList(self):
-        self._ModuleAutoGenList = []
-        self._LibraryAutoGenList = []
-        for ModuleFile in self.Platform.Modules:
-            Ma = ModuleAutoGen(
-                    self.Workspace,
-                    ModuleFile,
-                    self.BuildTarget,
-                    self.ToolChain,
-                    self.Arch,
-                    self.MetaFile
-                    )
-            if Ma not in self._ModuleAutoGenList:
-                self._ModuleAutoGenList.append(Ma)
-            for La in Ma.LibraryAutoGenList:
-                if La not in self._LibraryAutoGenList:
-                    self._LibraryAutoGenList.append(La)
-
-    ## Summarize ModuleAutoGen objects of all modules to be built for this platform
-    def _GetModuleAutoGenList(self):
-        if self._ModuleAutoGenList == None:
-            self._GetAutoGenObjectList()
-        return self._ModuleAutoGenList
-
-    ## Summarize ModuleAutoGen objects of all libraries to be built for this platform
-    def _GetLibraryAutoGenList(self):
-        if self._LibraryAutoGenList == None:
-            self._GetAutoGenObjectList()
-        return self._LibraryAutoGenList
-
-    ## Test if a module is supported by the platform
-    #
-    #  An error will be raised directly if the module or its arch is not supported
-    #  by the platform or current configuration
-    #
-    def ValidModule(self, Module):
-        return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances
-
-    ## Resolve the library classes in a module to library instances
-    #
-    # This method will not only resolve library classes but also sort the library
-    # instances according to the dependency-ship.
-    #
-    #   @param  Module      The module from which the library classes will be resolved
-    #
-    #   @retval library_list    List of library instances sorted
-    #
-    def ApplyLibraryInstance(self, Module):
-        ModuleType = Module.ModuleType
-
-        # for overridding library instances with module specific setting
-        PlatformModule = self.Platform.Modules[str(Module)]
-
-        # add forced library instances (specified under LibraryClasses sections)
-        for LibraryClass in self.Platform.LibraryClasses.GetKeys():
-            if LibraryClass.startswith("NULL"):
-                Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass]
-
-        # add forced library instances (specified in module overrides)
-        for LibraryClass in PlatformModule.LibraryClasses:
-            if LibraryClass.startswith("NULL"):
-                Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]
-
-        # R9 module
-        LibraryConsumerList = [Module]
-        Constructor         = []
-        ConsumedByList      = sdict()
-        LibraryInstance     = sdict()
-
-        EdkLogger.verbose("")
-        EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
-        while len(LibraryConsumerList) > 0:
-            M = LibraryConsumerList.pop()
-            for LibraryClassName in M.LibraryClasses:
-                if LibraryClassName not in LibraryInstance:
-                    # override library instance for this module
-                    if LibraryClassName in PlatformModule.LibraryClasses:
-                        LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]
-                    else:
-                        LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]
-                    if LibraryPath == None or LibraryPath == "":
-                        LibraryPath = M.LibraryClasses[LibraryClassName]
-                        if LibraryPath == None or LibraryPath == "":
-                            EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
-                                            "Instance of library class [%s] is not found" % LibraryClassName,
-                                            File=self.MetaFile,
-                                            ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))
-
-                    LibraryModule = self.BuildDatabase[LibraryPath, self.Arch]
-                    # for those forced library instance (NULL library), add a fake library class
-                    if LibraryClassName.startswith("NULL"):
-                        LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))
-                    elif LibraryModule.LibraryClass == None \
-                         or len(LibraryModule.LibraryClass) == 0 \
-                         or (ModuleType != 'USER_DEFINED'
-                             and ModuleType not in LibraryModule.LibraryClass[0].SupModList):
-                        # only USER_DEFINED can link against any library instance despite of its SupModList
-                        EdkLogger.error("build", OPTION_MISSING,
-                                        "Module type [%s] is not supported by library instance [%s]" \
-                                        % (ModuleType, LibraryPath), File=self.MetaFile,
-                                        ExtraData="consumed by [%s]" % str(Module))
-
-                    LibraryInstance[LibraryClassName] = LibraryModule
-                    LibraryConsumerList.append(LibraryModule)
-                    EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))
-                else:
-                    LibraryModule = LibraryInstance[LibraryClassName]
-
-                if LibraryModule == None:
-                    continue
-
-                if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:
-                    Constructor.append(LibraryModule)
-
-                if LibraryModule not in ConsumedByList:
-                    ConsumedByList[LibraryModule] = []
-                # don't add current module itself to consumer list
-                if M != Module:
-                    if M in ConsumedByList[LibraryModule]:
-                        continue
-                    ConsumedByList[LibraryModule].append(M)
-        #
-        # Initialize the sorted output list to the empty set
-        #
-        SortedLibraryList = []
-        #
-        # Q <- Set of all nodes with no incoming edges
-        #
-        LibraryList = [] #LibraryInstance.values()
-        Q = []
-        for LibraryClassName in LibraryInstance:
-            M = LibraryInstance[LibraryClassName]
-            LibraryList.append(M)
-            if ConsumedByList[M] == []:
-                Q.append(M)
-
-        #
-        # start the  DAG algorithm
-        #
-        while True:
-            EdgeRemoved = True
-            while Q == [] and EdgeRemoved:
-                EdgeRemoved = False
-                # for each node Item with a Constructor
-                for Item in LibraryList:
-                    if Item not in Constructor:
-                        continue
-                    # for each Node without a constructor with an edge e from Item to Node
-                    for Node in ConsumedByList[Item]:
-                        if Node in Constructor:
-                            continue
-                        # remove edge e from the graph if Node has no constructor
-                        ConsumedByList[Item].remove(Node)
-                        EdgeRemoved = True
-                        if ConsumedByList[Item] == []:
-                            # insert Item into Q
-                            Q.insert(0, Item)
-                            break
-                    if Q != []:
-                        break
-            # DAG is done if there's no more incoming edge for all nodes
-            if Q == []:
-                break
-
-            # remove node from Q
-            Node = Q.pop()
-            # output Node
-            SortedLibraryList.append(Node)
-
-            # for each node Item with an edge e from Node to Item do
-            for Item in LibraryList:
-                if Node not in ConsumedByList[Item]:
-                    continue
-                # remove edge e from the graph
-                ConsumedByList[Item].remove(Node)
-
-                if ConsumedByList[Item] != []:
-                    continue
-                # insert Item into Q, if Item has no other incoming edges
-                Q.insert(0, Item)
-
-        #
-        # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
-        #
-        for Item in LibraryList:
-            if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:
-                ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])
-                EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),
-                                ExtraData=ErrorMessage, File=self.MetaFile)
-            if Item not in SortedLibraryList:
-                SortedLibraryList.append(Item)
-
-        #
-        # Build the list of constructor and destructir names
-        # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
-        #
-        SortedLibraryList.reverse()
-        return SortedLibraryList
-
-
-    ## Override PCD setting (type, value, ...)
-    #
-    #   @param  ToPcd       The PCD to be overrided
-    #   @param  FromPcd     The PCD overrideing from
-    #
-    def _OverridePcd(self, ToPcd, FromPcd, Module=""):
-        #
-        # in case there's PCDs coming from FDF file, which have no type given.
-        # at this point, ToPcd.Type has the type found from dependent
-        # package
-        #
-        if FromPcd != None:
-            if ToPcd.Pending and FromPcd.Type not in [None, '']:
-                ToPcd.Type = FromPcd.Type
-            elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \
-                and ToPcd.Type != FromPcd.Type:
-                EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",
-                                ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
-                                          % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName,
-                                             ToPcd.Type, Module, FromPcd.Type),
-                                          File=self.MetaFile)
-
-            if FromPcd.MaxDatumSize not in [None, '']:
-                ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
-            if FromPcd.DefaultValue not in [None, '']:
-                ToPcd.DefaultValue = FromPcd.DefaultValue
-            if FromPcd.TokenValue not in [None, '']:
-                ToPcd.TokenValue = FromPcd.TokenValue
-            if FromPcd.MaxDatumSize not in [None, '']:
-                ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
-            if FromPcd.DatumType not in [None, '']:
-                ToPcd.DatumType = FromPcd.DatumType
-            if FromPcd.SkuInfoList not in [None, '', []]:
-                ToPcd.SkuInfoList = FromPcd.SkuInfoList
-
-            # check the validation of datum
-            IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)
-            if not IsValid:
-                EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,
-                                ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
-
-        if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:
-            EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \
-                            % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
-            Value = ToPcd.DefaultValue
-            if Value in [None, '']:
-                ToPcd.MaxDatumSize = 1
-            elif Value[0] == 'L':
-                ToPcd.MaxDatumSize = str(len(Value) * 2)
-            elif Value[0] == '{':
-                ToPcd.MaxDatumSize = str(len(Value.split(',')))
-            else:
-                ToPcd.MaxDatumSize = str(len(Value))
-
-        # apply default SKU for dynamic PCDS if specified one is not available
-        if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \
-            and ToPcd.SkuInfoList in [None, {}, '']:
-            if self.Platform.SkuName in self.Platform.SkuIds:
-                SkuName = self.Platform.SkuName
-            else:
-                SkuName = 'DEFAULT'
-            ToPcd.SkuInfoList = {
-                SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue)
-            }
-
-    ## Apply PCD setting defined platform to a module
-    #
-    #   @param  Module  The module from which the PCD setting will be overrided
-    #
-    #   @retval PCD_list    The list PCDs with settings from platform
-    #
-    def ApplyPcdSetting(self, Module, Pcds):
-        # for each PCD in module
-        for Name,Guid in Pcds:
-            PcdInModule = Pcds[Name,Guid]
-            # find out the PCD setting in platform
-            if (Name,Guid) in self.Platform.Pcds:
-                PcdInPlatform = self.Platform.Pcds[Name,Guid]
-            else:
-                PcdInPlatform = None
-            # then override the settings if any
-            self._OverridePcd(PcdInModule, PcdInPlatform, Module)
-            # resolve the VariableGuid value
-            for SkuId in PcdInModule.SkuInfoList:
-                Sku = PcdInModule.SkuInfoList[SkuId]
-                if Sku.VariableGuid == '': continue
-                Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList)
-                if Sku.VariableGuidValue == None:
-                    PackageList = "\n\t".join([str(P) for P in self.PackageList])
-                    EdkLogger.error(
-                                'build',
-                                RESOURCE_NOT_AVAILABLE,
-                                "Value of GUID [%s] is not found in" % Sku.VariableGuid,
-                                ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \
-                                                        % (Guid, Name, str(Module)),
-                                File=self.MetaFile
-                                )
-
-        # override PCD settings with module specific setting
-        if Module in self.Platform.Modules:
-            PlatformModule = self.Platform.Modules[str(Module)]
-            for Key  in PlatformModule.Pcds:
-                if Key in Pcds:
-                    self._OverridePcd(Pcds[Key], PlatformModule.Pcds[Key], Module)
-        return Pcds.values()
-
-    ## Resolve library names to library modules
-    #
-    # (for R8.x modules)
-    #
-    #   @param  Module  The module from which the library names will be resolved
-    #
-    #   @retval library_list    The list of library modules
-    #
-    def ResolveLibraryReference(self, Module):
-        EdkLogger.verbose("")
-        EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
-        LibraryConsumerList = [Module]
-
-        # "CompilerStub" is a must for R8 modules
-        if Module.Libraries:
-            Module.Libraries.append("CompilerStub")
-        LibraryList = []
-        while len(LibraryConsumerList) > 0:
-            M = LibraryConsumerList.pop()
-            for LibraryName in M.Libraries:
-                Library = self.Platform.LibraryClasses[LibraryName, ':dummy:']
-                if Library == None:
-                    for Key in self.Platform.LibraryClasses.data.keys():
-                        if LibraryName.upper() == Key.upper():
-                            Library = self.Platform.LibraryClasses[Key, ':dummy:']
-                            break
-                    if Library == None:
-                        EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),
-                            ExtraData="\t%s [%s]" % (str(Module), self.Arch))
-                        continue
-
-                if Library not in LibraryList:
-                    LibraryList.append(Library)
-                    LibraryConsumerList.append(Library)
-                    EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library)))
-        return LibraryList
-
-    ## Expand * in build option key
-    #
-    #   @param  Options     Options to be expanded
-    #
-    #   @retval options     Options expanded
-    #
-    def _ExpandBuildOption(self, Options):
-        BuildOptions = {}
-        FamilyMatch  = False
-        FamilyIsNull = True
-        for Key in Options:
-            Family = Key[0]
-            Target, Tag, Arch, Tool, Attr = Key[1].split("_")
-            # if tool chain family doesn't match, skip it
-            if Tool in self.ToolDefinition and Family != "":
-                FamilyIsNull = False
-                if self.ToolDefinition[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
-                    if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
-                        continue
-                elif Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
-                    continue
-                FamilyMatch = True
-            # expand any wildcard
-            if Target == "*" or Target == self.BuildTarget:
-                if Tag == "*" or Tag == self.ToolChain:
-                    if Arch == "*" or Arch == self.Arch:
-                        if Tool not in BuildOptions:
-                            BuildOptions[Tool] = {}
-                        if Attr != "FLAGS" or Attr not in BuildOptions[Tool]:
-                            BuildOptions[Tool][Attr] = Options[Key]
-                        else:
-                            # append options for the same tool
-                            BuildOptions[Tool][Attr] += " " + Options[Key]
-        # Build Option Family has been checked, which need't to be checked again for family.
-        if FamilyMatch or FamilyIsNull:
-            return BuildOptions
-        
-        for Key in Options:
-            Family = Key[0]
-            Target, Tag, Arch, Tool, Attr = Key[1].split("_")
-            # if tool chain family doesn't match, skip it
-            if Tool not in self.ToolDefinition or Family =="":
-                continue
-            # option has been added before
-            if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
-                continue
-
-            # expand any wildcard
-            if Target == "*" or Target == self.BuildTarget:
-                if Tag == "*" or Tag == self.ToolChain:
-                    if Arch == "*" or Arch == self.Arch:
-                        if Tool not in BuildOptions:
-                            BuildOptions[Tool] = {}
-                        if Attr != "FLAGS" or Attr not in BuildOptions[Tool]:
-                            BuildOptions[Tool][Attr] = Options[Key]
-                        else:
-                            # append options for the same tool
-                            BuildOptions[Tool][Attr] += " " + Options[Key]
-        return BuildOptions
-
-    ## Append build options in platform to a module
-    #
-    #   @param  Module  The module to which the build options will be appened
-    #
-    #   @retval options     The options appended with build options in platform
-    #
-    def ApplyBuildOption(self, Module):
-        PlatformOptions = self.BuildOption
-        ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)
-        if Module in self.Platform.Modules:
-            PlatformModule = self.Platform.Modules[str(Module)]
-            PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)
-        else:
-            PlatformModuleOptions = {}
-
-        AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() + PlatformModuleOptions.keys() + self.ToolDefinition.keys())
-        BuildOptions = {}
-        for Tool in AllTools:
-            if Tool not in BuildOptions:
-                BuildOptions[Tool] = {}
-
-            for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, PlatformModuleOptions]:
-                if Tool not in Options:
-                    continue
-                for Attr in Options[Tool]:
-                    Value = Options[Tool][Attr]
-                    if Attr not in BuildOptions[Tool]:
-                        BuildOptions[Tool][Attr] = ""
-                    # check if override is indicated
-                    if Value.startswith('='):
-                        BuildOptions[Tool][Attr] = Value[1:]
-                    else:
-                        BuildOptions[Tool][Attr] += " " + Value
-        return BuildOptions
-
-    Platform            = property(_GetPlatform)
-    Name                = property(_GetName)
-    Guid                = property(_GetGuid)
-    Version             = property(_GetVersion)
-
-    OutputDir           = property(_GetOutputDir)
-    BuildDir            = property(_GetBuildDir)
-    MakeFileDir         = property(_GetMakeFileDir)
-    FdfFile             = property(_GetFdfFile)
-
-    PcdTokenNumber      = property(_GetPcdTokenNumbers)    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
-    DynamicPcdList      = property(_GetDynamicPcdList)    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
-    NonDynamicPcdList   = property(_GetNonDynamicPcdList)    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
-    PackageList         = property(_GetPackageList)
-
-    ToolDefinition      = property(_GetToolDefinition)    # toolcode : tool path
-    ToolDefinitionFile  = property(_GetToolDefFile)    # toolcode : lib path
-    ToolChainFamily     = property(_GetToolChainFamily)
-    BuildRuleFamily     = property(_GetBuildRuleFamily)
-    BuildOption         = property(_GetBuildOptions)    # toolcode : option
-
-    BuildCommand        = property(_GetBuildCommand)
-    BuildRule           = property(_GetBuildRule)
-    ModuleAutoGenList   = property(_GetModuleAutoGenList)
-    LibraryAutoGenList  = property(_GetLibraryAutoGenList)
-
-## ModuleAutoGen class
-#
-# This class encapsules the AutoGen behaviors for the build tools. In addition to
-# the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according
-# to the [depex] section in module's inf file.
-#
-class ModuleAutoGen(AutoGen):
-    ## The real constructor of ModuleAutoGen
-    #
-    #  This method is not supposed to be called by users of ModuleAutoGen. It's
-    #  only used by factory method __new__() to do real initialization work for an
-    #  object of ModuleAutoGen
-    #
-    #   @param      Workspace           EdkIIWorkspaceBuild object
-    #   @param      ModuleFile          The path of module file
-    #   @param      Target              Build target (DEBUG, RELEASE)
-    #   @param      Toolchain           Name of tool chain
-    #   @param      Arch                The arch the module supports
-    #   @param      PlatformFile        Platform meta-file
-    #
-    def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):
-        EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch))
-        GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target)
-
-        self.Workspace = Workspace
-        self.WorkspaceDir = Workspace.WorkspaceDir
-
-        self.MetaFile = ModuleFile
-        self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)
-        # check if this module is employed by active platform
-        if not self.PlatformInfo.ValidModule(self.MetaFile):
-            EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \
-                              % (self.MetaFile, Arch))
-            return False
-
-        self.SourceDir = self.MetaFile.SubDir
-        self.SourceOverrideDir = None
-        # use overrided path defined in DSC file
-        if self.MetaFile.Key in GlobalData.gOverrideDir:
-            self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key]
-
-        self.ToolChain = Toolchain
-        self.BuildTarget = Target
-        self.Arch = Arch
-        self.ToolChainFamily = self.PlatformInfo.ToolChainFamily
-        self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily
-
-        self.IsMakeFileCreated = False
-        self.IsCodeFileCreated = False
-
-        self.BuildDatabase = self.Workspace.BuildDatabase
-
-        self._Module          = None
-        self._Name            = None
-        self._Guid            = None
-        self._Version         = None
-        self._ModuleType      = None
-        self._ComponentType   = None
-        self._PcdIsDriver     = None
-        self._AutoGenVersion  = None
-        self._LibraryFlag     = None
-        self._CustomMakefile  = None
-        self._Macro           = None
-
-        self._BuildDir        = None
-        self._OutputDir       = None
-        self._DebugDir        = None
-        self._MakeFileDir     = None
-
-        self._IncludePathList = None
-        self._AutoGenFileList = None
-        self._UnicodeFileList = None
-        self._SourceFileList  = None
-        self._ObjectFileList  = None
-        self._BinaryFileList  = None
-
-        self._DependentPackageList    = None
-        self._DependentLibraryList    = None
-        self._LibraryAutoGenList      = None
-        self._DerivedPackageList      = None
-        self._ModulePcdList           = None
-        self._LibraryPcdList          = None
-        self._GuidList                = None
-        self._ProtocolList            = None
-        self._PpiList                 = None
-        self._DepexList               = None
-        self._DepexExpressionList     = None
-        self._BuildOption             = None
-        self._BuildTargets            = None
-        self._IntroBuildTargetList    = None
-        self._FinalBuildTargetList    = None
-        self._FileTypes               = None
-        self._BuildRules              = None
-
-        return True
-
-    def __repr__(self):
-        return "%s [%s]" % (self.MetaFile, self.Arch)
-
-    # Macros could be used in build_rule.txt (also Makefile)
-    def _GetMacros(self):
-        if self._Macro == None:
-            self._Macro = sdict()
-            self._Macro["WORKSPACE"             ] = self.WorkspaceDir
-            self._Macro["MODULE_NAME"           ] = self.Name
-            self._Macro["MODULE_GUID"           ] = self.Guid
-            self._Macro["MODULE_VERSION"        ] = self.Version
-            self._Macro["MODULE_TYPE"           ] = self.ModuleType
-            self._Macro["MODULE_FILE"           ] = str(self.MetaFile)
-            self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName
-            self._Macro["MODULE_RELATIVE_DIR"   ] = self.SourceDir
-            self._Macro["MODULE_DIR"            ] = self.SourceDir
-
-            self._Macro["BASE_NAME"             ] = self.Name
-
-            self._Macro["ARCH"                  ] = self.Arch
-            self._Macro["TOOLCHAIN"             ] = self.ToolChain
-            self._Macro["TOOLCHAIN_TAG"         ] = self.ToolChain
-            self._Macro["TARGET"                ] = self.BuildTarget
-
-            self._Macro["BUILD_DIR"             ] = self.PlatformInfo.BuildDir
-            self._Macro["BIN_DIR"               ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)
-            self._Macro["LIB_DIR"               ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)
-            self._Macro["MODULE_BUILD_DIR"      ] = self.BuildDir
-            self._Macro["OUTPUT_DIR"            ] = self.OutputDir
-            self._Macro["DEBUG_DIR"             ] = self.DebugDir
-        return self._Macro
-
-    ## Return the module build data object
-    def _GetModule(self):
-        if self._Module == None:
-            self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch]
-        return self._Module
-
-    ## Return the module name
-    def _GetBaseName(self):
-        return self.Module.BaseName
-
-    ## Return the module SourceOverridePath
-    def _GetSourceOverridePath(self):
-        return self.Module.SourceOverridePath
-
-    ## Return the module meta-file GUID
-    def _GetGuid(self):
-        return self.Module.Guid
-
-    ## Return the module version
-    def _GetVersion(self):
-        return self.Module.Version
-
-    ## Return the module type
-    def _GetModuleType(self):
-        return self.Module.ModuleType
-
-    ## Return the component type (for R8.x style of module)
-    def _GetComponentType(self):
-        return self.Module.ComponentType
-
-    ## Return the build type
-    def _GetBuildType(self):
-        return self.Module.BuildType
-
-    ## Return the PCD_IS_DRIVER setting
-    def _GetPcdIsDriver(self):
-        return self.Module.PcdIsDriver
-
-    ## Return the autogen version, i.e. module meta-file version
-    def _GetAutoGenVersion(self):
-        return self.Module.AutoGenVersion
-
-    ## Check if the module is library or not
-    def _IsLibrary(self):
-        if self._LibraryFlag == None:
-            if self.Module.LibraryClass != None and self.Module.LibraryClass != []:
-                self._LibraryFlag = True
-            else:
-                self._LibraryFlag = False
-        return self._LibraryFlag
-
-    ## Return the directory to store intermediate files of the module
-    def _GetBuildDir(self):
-        if self._BuildDir == None:
-            self._BuildDir = path.join(
-                                    self.PlatformInfo.BuildDir,
-                                    self.Arch,
-                                    self.SourceDir,
-                                    self.MetaFile.BaseName
-                                    )
-            CreateDirectory(self._BuildDir)
-        return self._BuildDir
-
-    ## Return the directory to store the intermediate object files of the mdoule
-    def _GetOutputDir(self):
-        if self._OutputDir == None:
-            self._OutputDir = path.join(self.BuildDir, "OUTPUT")
-            CreateDirectory(self._OutputDir)
-        return self._OutputDir
-
-    ## Return the directory to store auto-gened source files of the mdoule
-    def _GetDebugDir(self):
-        if self._DebugDir == None:
-            self._DebugDir = path.join(self.BuildDir, "DEBUG")
-            CreateDirectory(self._DebugDir)
-        return self._DebugDir
-
-    ## Return the path of custom file
-    def _GetCustomMakefile(self):
-        if self._CustomMakefile == None:
-            self._CustomMakefile = {}
-            for Type in self.Module.CustomMakefile:
-                if Type in gMakeTypeMap:
-                    MakeType = gMakeTypeMap[Type]
-                else:
-                    MakeType = 'nmake'
-                if self.SourceOverrideDir != None:
-                    File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type])
-                    if not os.path.exists(File):
-                        File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
-                else:
-                    File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
-                self._CustomMakefile[MakeType] = File
-        return self._CustomMakefile
-
-    ## Return the directory of the makefile
-    #
-    #   @retval     string  The directory string of module's makefile
-    #
-    def _GetMakeFileDir(self):
-        return self.BuildDir
-
-    ## Return build command string
-    #
-    #   @retval     string  Build command string
-    #
-    def _GetBuildCommand(self):
-        return self.PlatformInfo.BuildCommand
-
-    ## Get object list of all packages the module and its dependent libraries belong to
-    #
-    #   @retval     list    The list of package object
-    #
-    def _GetDerivedPackageList(self):
-        PackageList = []
-        for M in [self.Module] + self.DependentLibraryList:
-            for Package in M.Packages:
-                if Package in PackageList:
-                    continue
-                PackageList.append(Package)
-        return PackageList
-
-    ## Merge dependency expression
-    #
-    #   @retval     list    The token list of the dependency expression after parsed
-    #
-    def _GetDepexTokenList(self):
-        if self._DepexList == None:
-            self._DepexList = {}
-            if self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
-                return self._DepexList
-
-            self._DepexList[self.ModuleType] = []
-
-            for ModuleType in self._DepexList:
-                DepexList = self._DepexList[ModuleType]
-                #
-                # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
-                #
-                for M in [self.Module] + self.DependentLibraryList:
-                    Inherited = False
-                    for D in M.Depex[self.Arch, ModuleType]:
-                        if DepexList != []:
-                            DepexList.append('AND')
-                        DepexList.append('(')
-                        DepexList.extend(D)
-                        if DepexList[-1] == 'END':  # no need of a END at this time
-                            DepexList.pop()
-                        DepexList.append(')')
-                        Inherited = True
-                    if Inherited:
-                        EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexList))
-                    if 'BEFORE' in DepexList or 'AFTER' in DepexList:
-                        break
-                if len(DepexList) > 0:
-                    EdkLogger.verbose('')
-        return self._DepexList
-
-    ## Merge dependency expression
-    #
-    #   @retval     list    The token list of the dependency expression after parsed
-    #
-    def _GetDepexExpressionTokenList(self):
-        if self._DepexExpressionList == None:
-            self._DepexExpressionList = {}
-            if self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
-                return self._DepexExpressionList
-
-            self._DepexExpressionList[self.ModuleType] = ''
-
-            for ModuleType in self._DepexExpressionList:
-                DepexExpressionList = self._DepexExpressionList[ModuleType]
-                #
-                # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
-                #
-                for M in [self.Module] + self.DependentLibraryList:
-                    Inherited = False
-                    for D in M.DepexExpression[self.Arch, ModuleType]:
-                        if DepexExpressionList != '':
-                            DepexExpressionList += ' AND '
-                        DepexExpressionList += '('
-                        DepexExpressionList += D
-                        DepexExpressionList = DepexExpressionList.rstrip('END').strip()
-                        DepexExpressionList += ')'
-                        Inherited = True
-                    if Inherited:
-                        EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexExpressionList))
-                    if 'BEFORE' in DepexExpressionList or 'AFTER' in DepexExpressionList:
-                        break
-                if len(DepexExpressionList) > 0:
-                    EdkLogger.verbose('')
-                self._DepexExpressionList[ModuleType] = DepexExpressionList
-        return self._DepexExpressionList
-
-    ## Return the list of specification version required for the module
-    #
-    #   @retval     list    The list of specification defined in module file
-    #
-    def _GetSpecification(self):
-        return self.Module.Specification
-
-    ## Tool option for the module build
-    #
-    #   @param      PlatformInfo    The object of PlatformBuildInfo
-    #   @retval     dict            The dict containing valid options
-    #
-    def _GetModuleBuildOption(self):
-        if self._BuildOption == None:
-            self._BuildOption = self.PlatformInfo.ApplyBuildOption(self.Module)
-        return self._BuildOption
-
-    ## Return a list of files which can be built from source
-    #
-    #  What kind of files can be built is determined by build rules in
-    #  $(WORKSPACE)/Conf/build_rule.txt and toolchain family.
-    #
-    def _GetSourceFileList(self):
-        if self._SourceFileList == None:
-            self._SourceFileList = []
-            for F in self.Module.Sources:
-                # match tool chain
-                if F.TagName != "" and F.TagName != self.ToolChain:
-                    EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, "
-                                    "but [%s] is needed" % (F.TagName, str(F), self.ToolChain))
-                    continue
-                # match tool chain family
-                if F.ToolChainFamily != "" and F.ToolChainFamily != self.ToolChainFamily:
-                    EdkLogger.debug(
-                                EdkLogger.DEBUG_0,
-                                "The file [%s] must be built by tools of [%s], " \
-                                "but current toolchain family is [%s]" \
-                                    % (str(F), F.ToolChainFamily, self.ToolChainFamily))
-                    continue
-
-                # add the file path into search path list for file including
-                if F.Dir not in self.IncludePathList and self.AutoGenVersion >= 0x00010005:
-                    self.IncludePathList.insert(0, F.Dir)
-                self._SourceFileList.append(F)
-                self._ApplyBuildRule(F, TAB_UNKNOWN_FILE)
-        return self._SourceFileList
-
-    ## Return the list of unicode files
-    def _GetUnicodeFileList(self):
-        if self._UnicodeFileList == None:
-            if TAB_UNICODE_FILE in self.FileTypes:
-                self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE]
-            else:
-                self._UnicodeFileList = []
-        return self._UnicodeFileList
-
-    ## Return a list of files which can be built from binary
-    #
-    #  "Build" binary files are just to copy them to build directory.
-    #
-    #   @retval     list            The list of files which can be built later
-    #
-    def _GetBinaryFiles(self):
-        if self._BinaryFileList == None:
-            self._BinaryFileList = []
-            for F in self.Module.Binaries:
-                if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget:
-                    continue
-                self._BinaryFileList.append(F)
-                self._ApplyBuildRule(F, F.Type)
-        return self._BinaryFileList
-
-    def _GetBuildRules(self):
-        if self._BuildRules == None:
-            BuildRules = {}
-            BuildRuleDatabase = self.PlatformInfo.BuildRule
-            for Type in BuildRuleDatabase.FileTypeList:
-                #first try getting build rule by BuildRuleFamily
-                RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.BuildRuleFamily]
-                if not RuleObject:
-                    # build type is always module type, but ...
-                    if self.ModuleType != self.BuildType:
-                        RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.BuildRuleFamily]
-                #second try getting build rule by ToolChainFamily
-                if not RuleObject:
-                    RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.ToolChainFamily]
-                    if not RuleObject:
-                        # build type is always module type, but ...
-                        if self.ModuleType != self.BuildType:
-                            RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.ToolChainFamily]
-                if not RuleObject:
-                    continue
-                RuleObject = RuleObject.Instantiate(self.Macros)
-                BuildRules[Type] = RuleObject
-                for Ext in RuleObject.SourceFileExtList:
-                    BuildRules[Ext] = RuleObject
-            self._BuildRules = BuildRules
-        return self._BuildRules
-
-    def _ApplyBuildRule(self, File, FileType):
-        if self._BuildTargets == None:
-            self._IntroBuildTargetList = set()
-            self._FinalBuildTargetList = set()
-            self._BuildTargets = {}
-            self._FileTypes = {}
-
-        LastTarget = None
-        RuleChain = []
-        SourceList = [File]
-        Index = 0
-        while Index < len(SourceList):
-            Source = SourceList[Index]
-            Index = Index + 1
-
-            if Source != File:
-                CreateDirectory(Source.Dir)
-
-            if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._BinaryFileList:
-                RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]
-            elif FileType in self.BuildRules:
-                RuleObject = self.BuildRules[FileType]
-            elif Source.Ext in self.BuildRules:
-                RuleObject = self.BuildRules[Source.Ext]
-            else:
-                # stop at no more rules
-                if LastTarget:
-                    self._FinalBuildTargetList.add(LastTarget)
-                break
-
-            FileType = RuleObject.SourceFileType
-            if FileType not in self._FileTypes:
-                self._FileTypes[FileType] = set()
-            self._FileTypes[FileType].add(Source)
-
-            # stop at STATIC_LIBRARY for library
-            if self.IsLibrary and FileType == TAB_STATIC_LIBRARY:
-                if LastTarget:
-                    self._FinalBuildTargetList.add(LastTarget)
-                break
-
-            Target = RuleObject.Apply(Source)
-            if not Target:
-                if LastTarget:
-                    self._FinalBuildTargetList.add(LastTarget)
-                break
-            elif not Target.Outputs:
-                # Only do build for target with outputs
-                self._FinalBuildTargetList.add(Target)
-
-            if FileType not in self._BuildTargets:
-                self._BuildTargets[FileType] = set()
-            self._BuildTargets[FileType].add(Target)
-
-            if not Source.IsBinary and Source == File:
-                self._IntroBuildTargetList.add(Target)
-
-            # to avoid cyclic rule
-            if FileType in RuleChain:
-                break
-
-            RuleChain.append(FileType)
-            SourceList.extend(Target.Outputs)
-            LastTarget = Target
-            FileType = TAB_UNKNOWN_FILE
-
-    def _GetTargets(self):
-        if self._BuildTargets == None:
-            self._IntroBuildTargetList = set()
-            self._FinalBuildTargetList = set()
-            self._BuildTargets = {}
-            self._FileTypes = {}
-
-        #TRICK: call _GetSourceFileList to apply build rule for binary files
-        if self.SourceFileList:
-            pass
-
-        #TRICK: call _GetBinaryFileList to apply build rule for binary files
-        if self.BinaryFileList:
-            pass
-
-        return self._BuildTargets
-
-    def _GetIntroTargetList(self):
-        self._GetTargets()
-        return self._IntroBuildTargetList
-
-    def _GetFinalTargetList(self):
-        self._GetTargets()
-        return self._FinalBuildTargetList
-
-    def _GetFileTypes(self):
-        self._GetTargets()
-        return self._FileTypes
-
-    ## Get the list of package object the module depends on
-    #
-    #   @retval     list    The package object list
-    #
-    def _GetDependentPackageList(self):
-        return self.Module.Packages
-
-    ## Return the list of auto-generated code file
-    #
-    #   @retval     list        The list of auto-generated file
-    #
-    def _GetAutoGenFileList(self):
-        UniStringAutoGenC = True
-        UniStringBinBuffer = None
-        if self.BuildType == 'UEFI_HII':
-            UniStringBinBuffer = StringIO()
-            UniStringAutoGenC = False
-        if self._AutoGenFileList == None:
-            self._AutoGenFileList = {}
-            AutoGenC = TemplateString()
-            AutoGenH = TemplateString()
-            StringH = TemplateString()
-            GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer)
-            if str(AutoGenC) != "" and TAB_C_CODE_FILE in self.FileTypes:
-                AutoFile = PathClass(gAutoGenCodeFileName, self.DebugDir)
-                self._AutoGenFileList[AutoFile] = str(AutoGenC)
-                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
-            if str(AutoGenH) != "":
-                AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir)
-                self._AutoGenFileList[AutoFile] = str(AutoGenH)
-                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
-            if str(StringH) != "":
-                AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir)
-                self._AutoGenFileList[AutoFile] = str(StringH)
-                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
-            if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "":
-                AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)
-                self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue()
-                AutoFile.IsBinary = True
-                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
-            if UniStringBinBuffer != None:
-                UniStringBinBuffer.close()
-        return self._AutoGenFileList
-
-    ## Return the list of library modules explicitly or implicityly used by this module
-    def _GetLibraryList(self):
-        if self._DependentLibraryList == None:
-            # only merge library classes and PCD for non-library module
-            if self.IsLibrary:
-                self._DependentLibraryList = []
-            else:
-                if self.AutoGenVersion < 0x00010005:
-                    self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module)
-                else:
-                    self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)
-        return self._DependentLibraryList
-
-    ## Get the list of PCDs from current module
-    #
-    #   @retval     list                    The list of PCD
-    #
-    def _GetModulePcdList(self):
-        if self._ModulePcdList == None:
-            # apply PCD settings from platform
-            self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)
-        return self._ModulePcdList
-
-    ## Get the list of PCDs from dependent libraries
-    #
-    #   @retval     list                    The list of PCD
-    #
-    def _GetLibraryPcdList(self):
-        if self._LibraryPcdList == None:
-            Pcds = {}
-            if not self.IsLibrary:
-                # get PCDs from dependent libraries
-                for Library in self.DependentLibraryList:
-                    for Key in Library.Pcds:
-                        # skip duplicated PCDs
-                        if Key in self.Module.Pcds or Key in Pcds:
-                            continue
-                        Pcds[Key] = copy.copy(Library.Pcds[Key])
-                # apply PCD settings from platform
-                self._LibraryPcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, Pcds)
-            else:
-                self._LibraryPcdList = []
-        return self._LibraryPcdList
-
-    ## Get the GUID value mapping
-    #
-    #   @retval     dict    The mapping between GUID cname and its value
-    #
-    def _GetGuidList(self):
-        if self._GuidList == None:
-            self._GuidList = self.Module.Guids
-            for Library in self.DependentLibraryList:
-                self._GuidList.update(Library.Guids)
-        return self._GuidList
-
-    ## Get the protocol value mapping
-    #
-    #   @retval     dict    The mapping between protocol cname and its value
-    #
-    def _GetProtocolList(self):
-        if self._ProtocolList == None:
-            self._ProtocolList = self.Module.Protocols
-            for Library in self.DependentLibraryList:
-                self._ProtocolList.update(Library.Protocols)
-        return self._ProtocolList
-
-    ## Get the PPI value mapping
-    #
-    #   @retval     dict    The mapping between PPI cname and its value
-    #
-    def _GetPpiList(self):
-        if self._PpiList == None:
-            self._PpiList = self.Module.Ppis
-            for Library in self.DependentLibraryList:
-                self._PpiList.update(Library.Ppis)
-        return self._PpiList
-
-    ## Get the list of include search path
-    #
-    #   @retval     list                    The list path
-    #
-    def _GetIncludePathList(self):
-        if self._IncludePathList == None:
-            self._IncludePathList = []
-            if self.AutoGenVersion < 0x00010005:
-                for Inc in self.Module.Includes:
-                    if Inc not in self._IncludePathList:
-                        self._IncludePathList.append(Inc)
-                    # for r8 modules
-                    Inc = path.join(Inc, self.Arch.capitalize())
-                    if os.path.exists(Inc) and Inc not in self._IncludePathList:
-                        self._IncludePathList.append(Inc)
-                # r8 module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
-                self._IncludePathList.append(self.DebugDir)
-            else:
-                self._IncludePathList.append(self.MetaFile.Dir)
-                self._IncludePathList.append(self.DebugDir)
-
-            for Package in self.Module.Packages:
-                PackageDir = path.join(self.WorkspaceDir, Package.MetaFile.Dir)
-                if PackageDir not in self._IncludePathList:
-                    self._IncludePathList.append(PackageDir)
-                for Inc in Package.Includes:
-                    if Inc not in self._IncludePathList:
-                        self._IncludePathList.append(str(Inc))
-        return self._IncludePathList
-
-    ## Create makefile for the module and its dependent libraries
-    #
-    #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of
-    #                                       dependent libraries will be created
-    #
-    def CreateMakeFile(self, CreateLibraryMakeFile=True):
-        if self.IsMakeFileCreated:
-            return
-
-        if not self.IsLibrary and CreateLibraryMakeFile:
-            for LibraryAutoGen in self.LibraryAutoGenList:
-                LibraryAutoGen.CreateMakeFile()
-
-        if len(self.CustomMakefile) == 0:
-            Makefile = GenMake.ModuleMakefile(self)
-        else:
-            Makefile = GenMake.CustomMakefile(self)
-        if Makefile.Generate():
-            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for module %s [%s]" %
-                            (self.Name, self.Arch))
-        else:
-            EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %
-                            (self.Name, self.Arch))
-
-        self.IsMakeFileCreated = True
-
-    ## Create autogen code for the module and its dependent libraries
-    #
-    #   @param      CreateLibraryCodeFile   Flag indicating if or not the code of
-    #                                       dependent libraries will be created
-    #
-    def CreateCodeFile(self, CreateLibraryCodeFile=True):
-        if self.IsCodeFileCreated:
-            return
-
-        if not self.IsLibrary and CreateLibraryCodeFile:
-            for LibraryAutoGen in self.LibraryAutoGenList:
-                LibraryAutoGen.CreateCodeFile()
-
-        AutoGenList = []
-        IgoredAutoGenList = []
-
-        for File in self.AutoGenFileList:
-            if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary):
-                #Ignore R8 AutoGen.c
-                if self.AutoGenVersion < 0x00010005 and File.Name == 'AutoGen.c':
-                        continue
-
-                AutoGenList.append(str(File))
-            else:
-                IgoredAutoGenList.append(str(File))
-
-        # Skip the following code for EDK I inf
-        if self.AutoGenVersion < 0x00010005:
-            return
-
-        for ModuleType in self.DepexList:
-            if len(self.DepexList[ModuleType]) == 0:
-                continue
-            Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True)
-            DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}
-
-            if Dpx.Generate(path.join(self.OutputDir, DpxFile)):
-                AutoGenList.append(str(DpxFile))
-            else:
-                IgoredAutoGenList.append(str(DpxFile))
-
-        if IgoredAutoGenList == []:
-            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] files for module %s [%s]" %
-                            (" ".join(AutoGenList), self.Name, self.Arch))
-        elif AutoGenList == []:
-            EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of [%s] files for module %s [%s]" %
-                            (" ".join(IgoredAutoGenList), self.Name, self.Arch))
-        else:
-            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] (skipped %s) files for module %s [%s]" %
-                            (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))
-
-        self.IsCodeFileCreated = True
-        return AutoGenList
-
-    ## Summarize the ModuleAutoGen objects of all libraries used by this module
-    def _GetLibraryAutoGenList(self):
-        if self._LibraryAutoGenList == None:
-            self._LibraryAutoGenList = []
-            for Library in self.DependentLibraryList:
-                La = ModuleAutoGen(
-                        self.Workspace,
-                        Library.MetaFile,
-                        self.BuildTarget,
-                        self.ToolChain,
-                        self.Arch,
-                        self.PlatformInfo.MetaFile
-                        )
-                if La not in self._LibraryAutoGenList:
-                    self._LibraryAutoGenList.append(La)
-                    for Lib in La.CodaTargetList:
-                        self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)
-        return self._LibraryAutoGenList
-
-    ## Return build command string
-    #
-    #   @retval     string  Build command string
-    #
-    def _GetBuildCommand(self):
-        return self.PlatformInfo.BuildCommand
-
-
-    Module          = property(_GetModule)
-    Name            = property(_GetBaseName)
-    Guid            = property(_GetGuid)
-    Version         = property(_GetVersion)
-    ModuleType      = property(_GetModuleType)
-    ComponentType   = property(_GetComponentType)
-    BuildType       = property(_GetBuildType)
-    PcdIsDriver     = property(_GetPcdIsDriver)
-    AutoGenVersion  = property(_GetAutoGenVersion)
-    Macros          = property(_GetMacros)
-    Specification   = property(_GetSpecification)
-
-    IsLibrary       = property(_IsLibrary)
-
-    BuildDir        = property(_GetBuildDir)
-    OutputDir       = property(_GetOutputDir)
-    DebugDir        = property(_GetDebugDir)
-    MakeFileDir     = property(_GetMakeFileDir)
-    CustomMakefile  = property(_GetCustomMakefile)
-
-    IncludePathList = property(_GetIncludePathList)
-    AutoGenFileList = property(_GetAutoGenFileList)
-    UnicodeFileList = property(_GetUnicodeFileList)
-    SourceFileList  = property(_GetSourceFileList)
-    BinaryFileList  = property(_GetBinaryFiles) # FileType : [File List]
-    Targets         = property(_GetTargets)
-    IntroTargetList = property(_GetIntroTargetList)
-    CodaTargetList  = property(_GetFinalTargetList)
-    FileTypes       = property(_GetFileTypes)
-    BuildRules      = property(_GetBuildRules)
-
-    DependentPackageList    = property(_GetDependentPackageList)
-    DependentLibraryList    = property(_GetLibraryList)
-    LibraryAutoGenList      = property(_GetLibraryAutoGenList)
-    DerivedPackageList      = property(_GetDerivedPackageList)
-
-    ModulePcdList           = property(_GetModulePcdList)
-    LibraryPcdList          = property(_GetLibraryPcdList)
-    GuidList                = property(_GetGuidList)
-    ProtocolList            = property(_GetProtocolList)
-    PpiList                 = property(_GetPpiList)
-    DepexList               = property(_GetDepexTokenList)
-    DepexExpressionList     = property(_GetDepexExpressionTokenList)
-    BuildOption             = property(_GetModuleBuildOption)
-    BuildCommand            = property(_GetBuildCommand)
-
-# This acts like the main() function for the script, unless it is 'import'ed into another script.
-if __name__ == '__main__':
-    pass
-
+## @file\r
+# Generate AutoGen.h, AutoGen.c and *.depex files\r
+#\r
+# Copyright (c) 2007 - 2010, Intel Corporation\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+## Import Modules\r
+#\r
+import os\r
+import re\r
+import os.path as path\r
+import copy\r
+\r
+import GenC\r
+import GenMake\r
+import GenDepex\r
+from StringIO import StringIO\r
+\r
+from StrGather import *\r
+from BuildEngine import BuildRule\r
+\r
+from Common.BuildToolError import *\r
+from Common.DataType import *\r
+from Common.Misc import *\r
+from Common.String import *\r
+import Common.GlobalData as GlobalData\r
+from GenFds.FdfParser import *\r
+from CommonDataClass.CommonClass import SkuInfoClass\r
+from Workspace.BuildClassObject import *\r
+\r
+## Regular expression for splitting Dependency Expression stirng into tokens\r
+gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r
+\r
+## Mapping Makefile type\r
+gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}\r
+\r
+\r
+## Build rule configuration file\r
+gBuildRuleFile = 'Conf/build_rule.txt'\r
+\r
+## default file name for AutoGen\r
+gAutoGenCodeFileName = "AutoGen.c"\r
+gAutoGenHeaderFileName = "AutoGen.h"\r
+gAutoGenStringFileName = "%(module_name)sStrDefs.h"\r
+gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk"\r
+gAutoGenDepexFileName = "%(module_name)s.depex"\r
+\r
+## Base class for AutoGen\r
+#\r
+#   This class just implements the cache mechanism of AutoGen objects.\r
+#\r
+class AutoGen(object):\r
+    # database to maintain the objects of xxxAutoGen\r
+    _CACHE_ = {}    # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}\r
+\r
+    ## Factory method\r
+    #\r
+    #   @param  Class           class object of real AutoGen class\r
+    #                           (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)\r
+    #   @param  Workspace       Workspace directory or WorkspaceAutoGen object\r
+    #   @param  MetaFile        The path of meta file\r
+    #   @param  Target          Build target\r
+    #   @param  Toolchain       Tool chain name\r
+    #   @param  Arch            Target arch\r
+    #   @param  *args           The specific class related parameters\r
+    #   @param  **kwargs        The specific class related dict parameters\r
+    #\r
+    def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
+        # check if the object has been created\r
+        Key = (Target, Toolchain)\r
+        if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \\r
+           or MetaFile not in Class._CACHE_[Key][Arch]:\r
+            AutoGenObject = super(AutoGen, Class).__new__(Class)\r
+            # call real constructor\r
+            if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
+                return None\r
+            if Key not in Class._CACHE_:\r
+                Class._CACHE_[Key] = {}\r
+            if Arch not in Class._CACHE_[Key]:\r
+                Class._CACHE_[Key][Arch] = {}\r
+            Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject\r
+        else:\r
+            AutoGenObject = Class._CACHE_[Key][Arch][MetaFile]\r
+\r
+        return AutoGenObject\r
+\r
+    ## hash() operator\r
+    #\r
+    #  The file path of platform file will be used to represent hash value of this object\r
+    #\r
+    #   @retval int     Hash value of the file path of platform file\r
+    #\r
+    def __hash__(self):\r
+        return hash(self.MetaFile)\r
+\r
+    ## str() operator\r
+    #\r
+    #  The file path of platform file will be used to represent this object\r
+    #\r
+    #   @retval string  String of platform file path\r
+    #\r
+    def __str__(self):\r
+        return str(self.MetaFile)\r
+\r
+    ## "==" operator\r
+    def __eq__(self, Other):\r
+        return Other and self.MetaFile == Other\r
+\r
+## Workspace AutoGen class\r
+#\r
+#   This class is used mainly to control the whole platform build for different\r
+# architecture. This class will generate top level makefile.\r
+#\r
+class WorkspaceAutoGen(AutoGen):\r
+    ## Real constructor of WorkspaceAutoGen\r
+    #\r
+    # This method behaves the same as __init__ except that it needs explict invoke\r
+    # (in super class's __new__ method)\r
+    #\r
+    #   @param  WorkspaceDir            Root directory of workspace\r
+    #   @param  ActivePlatform          Meta-file of active platform\r
+    #   @param  Target                  Build target\r
+    #   @param  Toolchain               Tool chain name\r
+    #   @param  ArchList                List of architecture of current build\r
+    #   @param  MetaFileDb              Database containing meta-files\r
+    #   @param  BuildConfig             Configuration of build\r
+    #   @param  ToolDefinition          Tool chain definitions\r
+    #   @param  FlashDefinitionFile     File of flash definition\r
+    #   @param  Fds                     FD list to be generated\r
+    #   @param  Fvs                     FV list to be generated\r
+    #   @param  SkuId                   SKU id from command line\r
+    #\r
+    def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,\r
+              BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=[], Fvs=[], SkuId=''):\r
+        self.MetaFile       = ActivePlatform.MetaFile\r
+        self.WorkspaceDir   = WorkspaceDir\r
+        self.Platform       = ActivePlatform\r
+        self.BuildTarget    = Target\r
+        self.ToolChain      = Toolchain\r
+        self.ArchList       = ArchList\r
+        self.SkuId          = SkuId\r
+\r
+        self.BuildDatabase  = MetaFileDb\r
+        self.TargetTxt      = BuildConfig\r
+        self.ToolDef        = ToolDefinition\r
+        self.FdfFile        = FlashDefinitionFile\r
+        self.FdTargetList   = Fds\r
+        self.FvTargetList   = Fvs\r
+        self.AutoGenObjectList = []\r
+\r
+        # there's many relative directory operations, so ...\r
+        os.chdir(self.WorkspaceDir)\r
+\r
+        # parse FDF file to get PCDs in it, if any\r
+        if self.FdfFile != None and self.FdfFile != '':\r
+            Fdf = FdfParser(self.FdfFile.Path)\r
+            Fdf.ParseFile()\r
+            PcdSet = Fdf.Profile.PcdDict\r
+            ModuleList = Fdf.Profile.InfList\r
+            self.FdfProfile = Fdf.Profile\r
+        else:\r
+            PcdSet = {}\r
+            ModuleList = []\r
+            self.FdfProfile = None\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
+            #\r
+            # Explicitly collect platform's dynamic PCDs\r
+            #\r
+            Pa.CollectPlatformDynamicPcds()\r
+            self.AutoGenObjectList.append(Pa)\r
+\r
+        self._BuildDir = None\r
+        self._FvDir = None\r
+        self._MakeFileDir = None\r
+        self._BuildCommand = None\r
+\r
+        return True\r
+\r
+    def __repr__(self):\r
+        return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList))\r
+\r
+    ## Return the directory to store FV files\r
+    def _GetFvDir(self):\r
+        if self._FvDir == None:\r
+            self._FvDir = path.join(self.BuildDir, 'FV')\r
+        return self._FvDir\r
+\r
+    ## Return the directory to store all intermediate and final files built\r
+    def _GetBuildDir(self):\r
+        return self.AutoGenObjectList[0].BuildDir\r
+\r
+    ## Return the build output directory platform specifies\r
+    def _GetOutputDir(self):\r
+        return self.Platform.OutputDirectory\r
+\r
+    ## Return platform name\r
+    def _GetName(self):\r
+        return self.Platform.PlatformName\r
+\r
+    ## Return meta-file GUID\r
+    def _GetGuid(self):\r
+        return self.Platform.Guid\r
+\r
+    ## Return platform version\r
+    def _GetVersion(self):\r
+        return self.Platform.Version\r
+\r
+    ## Return paths of tools\r
+    def _GetToolDefinition(self):\r
+        return self.AutoGenObjectList[0].ToolDefinition\r
+\r
+    ## Return directory of platform makefile\r
+    #\r
+    #   @retval     string  Makefile directory\r
+    #\r
+    def _GetMakeFileDir(self):\r
+        if self._MakeFileDir == None:\r
+            self._MakeFileDir = self.BuildDir\r
+        return self._MakeFileDir\r
+\r
+    ## Return build command string\r
+    #\r
+    #   @retval     string  Build command string\r
+    #\r
+    def _GetBuildCommand(self):\r
+        if self._BuildCommand == None:\r
+            # BuildCommand should be all the same. So just get one from platform AutoGen\r
+            self._BuildCommand = self.AutoGenObjectList[0].BuildCommand\r
+        return self._BuildCommand\r
+\r
+    ## Create makefile for the platform and mdoules in it\r
+    #\r
+    #   @param      CreateDepsMakeFile      Flag indicating if the makefile for\r
+    #                                       modules will be created as well\r
+    #\r
+    def CreateMakeFile(self, CreateDepsMakeFile=False):\r
+        # create makefile for platform\r
+        Makefile = GenMake.TopLevelMakefile(self)\r
+        if Makefile.Generate():\r
+            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for platform [%s] %s\n" %\r
+                            (self.MetaFile, self.ArchList))\r
+        else:\r
+            EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for platform [%s] %s\n" %\r
+                            (self.MetaFile, self.ArchList))\r
+\r
+        if CreateDepsMakeFile:\r
+            for Pa in self.AutoGenObjectList:\r
+                Pa.CreateMakeFile(CreateDepsMakeFile)\r
+\r
+    ## Create autogen code for platform and modules\r
+    #\r
+    #  Since there's no autogen code for platform, this method will do nothing\r
+    #  if CreateModuleCodeFile is set to False.\r
+    #\r
+    #   @param      CreateDepsCodeFile      Flag indicating if creating module's\r
+    #                                       autogen code file or not\r
+    #\r
+    def CreateCodeFile(self, CreateDepsCodeFile=False):\r
+        if not CreateDepsCodeFile:\r
+            return\r
+        for Pa in self.AutoGenObjectList:\r
+            Pa.CreateCodeFile(CreateDepsCodeFile)\r
+\r
+    Name                = property(_GetName)\r
+    Guid                = property(_GetGuid)\r
+    Version             = property(_GetVersion)\r
+    OutputDir           = property(_GetOutputDir)\r
+\r
+    ToolDefinition      = property(_GetToolDefinition)       # toolcode : tool path\r
+\r
+    BuildDir            = property(_GetBuildDir)\r
+    FvDir               = property(_GetFvDir)\r
+    MakeFileDir         = property(_GetMakeFileDir)\r
+    BuildCommand        = property(_GetBuildCommand)\r
+\r
+## AutoGen class for platform\r
+#\r
+#  PlatformAutoGen class will process the original information in platform\r
+#  file in order to generate makefile for platform.\r
+#\r
+class PlatformAutoGen(AutoGen):\r
+    #\r
+    # Used to store all PCDs for both PEI and DXE phase, in order to generate \r
+    # correct PCD database\r
+    # \r
+    _DynaPcdList_ = []\r
+    _NonDynaPcdList_ = []\r
+\r
+    ## The real constructor of PlatformAutoGen\r
+    #\r
+    #  This method is not supposed to be called by users of PlatformAutoGen. It's\r
+    #  only used by factory method __new__() to do real initialization work for an\r
+    #  object of PlatformAutoGen\r
+    #\r
+    #   @param      Workspace       WorkspaceAutoGen object\r
+    #   @param      PlatformFile    Platform file (DSC file)\r
+    #   @param      Target          Build target (DEBUG, RELEASE)\r
+    #   @param      Toolchain       Name of tool chain\r
+    #   @param      Arch            arch of the platform supports\r
+    #\r
+    def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):\r
+        EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch))\r
+        GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target)\r
+\r
+        self.MetaFile = PlatformFile\r
+        self.Workspace = Workspace\r
+        self.WorkspaceDir = Workspace.WorkspaceDir\r
+        self.ToolChain = Toolchain\r
+        self.BuildTarget = Target\r
+        self.Arch = Arch\r
+        self.SourceDir = PlatformFile.SubDir\r
+        self.SourceOverrideDir = None\r
+        self.FdTargetList = self.Workspace.FdTargetList\r
+        self.FvTargetList = self.Workspace.FvTargetList\r
+        self.AllPcdList = []\r
+\r
+        # flag indicating if the makefile/C-code file has been created or not\r
+        self.IsMakeFileCreated  = False\r
+        self.IsCodeFileCreated  = False\r
+\r
+        self._Platform   = None\r
+        self._Name       = None\r
+        self._Guid       = None\r
+        self._Version    = None\r
+\r
+        self._BuildRule = None\r
+        self._SourceDir = None\r
+        self._BuildDir = None\r
+        self._OutputDir = None\r
+        self._FvDir = None\r
+        self._MakeFileDir = None\r
+        self._FdfFile = None\r
+\r
+        self._PcdTokenNumber = None    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber\r
+        self._DynamicPcdList = None    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
+        self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
+\r
+        self._ToolDefinitions = None\r
+        self._ToolDefFile = None          # toolcode : tool path\r
+        self._ToolChainFamily = None\r
+        self._BuildRuleFamily = None\r
+        self._BuildOption = None          # toolcode : option\r
+        self._PackageList = None\r
+        self._ModuleAutoGenList  = None\r
+        self._LibraryAutoGenList = None\r
+        self._BuildCommand = None\r
+\r
+        # get the original module/package/platform objects\r
+        self.BuildDatabase = Workspace.BuildDatabase\r
+        return True\r
+\r
+    def __repr__(self):\r
+        return "%s [%s]" % (self.MetaFile, self.Arch)\r
+\r
+    ## Create autogen code for platform and modules\r
+    #\r
+    #  Since there's no autogen code for platform, this method will do nothing\r
+    #  if CreateModuleCodeFile is set to False.\r
+    #\r
+    #   @param      CreateModuleCodeFile    Flag indicating if creating module's\r
+    #                                       autogen code file or not\r
+    #\r
+    def CreateCodeFile(self, CreateModuleCodeFile=False):\r
+        # only module has code to be greated, so do nothing if CreateModuleCodeFile is False\r
+        if self.IsCodeFileCreated or not CreateModuleCodeFile:\r
+            return\r
+\r
+        for Ma in self.ModuleAutoGenList:\r
+            Ma.CreateCodeFile(True)\r
+\r
+        # don't do this twice\r
+        self.IsCodeFileCreated = True\r
+\r
+    ## Create makefile for the platform and mdoules in it\r
+    #\r
+    #   @param      CreateModuleMakeFile    Flag indicating if the makefile for\r
+    #                                       modules will be created as well\r
+    #\r
+    def CreateMakeFile(self, CreateModuleMakeFile=False):\r
+        if CreateModuleMakeFile:\r
+            for ModuleFile in self.Platform.Modules:\r
+                Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,\r
+                                   self.ToolChain, self.Arch, self.MetaFile)\r
+                Ma.CreateMakeFile(True)\r
+\r
+        # no need to create makefile for the platform more than once\r
+        if self.IsMakeFileCreated:\r
+            return\r
+\r
+        # create makefile for platform\r
+        Makefile = GenMake.PlatformMakefile(self)\r
+        if Makefile.Generate():\r
+            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for platform [%s] [%s]\n" %\r
+                            (self.MetaFile, self.Arch))\r
+        else:\r
+            EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for platform [%s] [%s]\n" %\r
+                            (self.MetaFile, self.Arch))\r
+        self.IsMakeFileCreated = True\r
+\r
+    ## Collect dynamic PCDs\r
+    #\r
+    #  Gather dynamic PCDs list from each module and their settings from platform\r
+    #  This interface should be invoked explicitly when platform action is created.\r
+    #\r
+    def CollectPlatformDynamicPcds(self):\r
+        # for gathering error information\r
+        NoDatumTypePcdList = set()\r
+\r
+        self._GuidValue = {}\r
+        for F in self.Platform.Modules.keys():\r
+            M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile)\r
+            #GuidValue.update(M.Guids)\r
+            \r
+            self.Platform.Modules[F].M = M\r
+            \r
+            for PcdFromModule in M.ModulePcdList+M.LibraryPcdList:\r
+                # make sure that the "VOID*" kind of datum has MaxDatumSize set\r
+                if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize == None:\r
+                    NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, F))\r
+\r
+                if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:\r
+                    #\r
+                    # If a dynamic PCD used by a PEM module/PEI module & DXE module,\r
+                    # it should be stored in Pcd PEI database, If a dynamic only\r
+                    # used by DXE module, it should be stored in DXE PCD database.\r
+                    # The default Phase is DXE\r
+                    #\r
+                    if M.ModuleType in ["PEIM", "PEI_CORE"]:\r
+                        PcdFromModule.Phase = "PEI"\r
+                    if PcdFromModule not in self._DynaPcdList_:\r
+                        self._DynaPcdList_.append(PcdFromModule)\r
+                    elif PcdFromModule.Phase == 'PEI':\r
+                        # overwrite any the same PCD existing, if Phase is PEI\r
+                        Index = self._DynaPcdList_.index(PcdFromModule)\r
+                        self._DynaPcdList_[Index] = PcdFromModule\r
+                elif PcdFromModule not in self._NonDynaPcdList_:\r
+                    self._NonDynaPcdList_.append(PcdFromModule)\r
+\r
+        # print out error information and break the build, if error found\r
+        if len(NoDatumTypePcdList) > 0:\r
+            NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)\r
+            EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",\r
+                            File=self.MetaFile,\r
+                            ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"\r
+                                      % NoDatumTypePcdListString)\r
+        self._NonDynamicPcdList = self._NonDynaPcdList_\r
+        self._DynamicPcdList = self._DynaPcdList_\r
+        self.AllPcdList = self._NonDynamicPcdList + self._DynamicPcdList\r
+        \r
+        #\r
+        # Sort dynamic PCD list to:\r
+        # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should \r
+        #    try to be put header of dynamicd List\r
+        # 2) If PCD is HII type, the PCD item should be put after unicode type PCD\r
+        #\r
+        # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.\r
+        #\r
+        UnicodePcdArray = []\r
+        HiiPcdArray     = []\r
+        OtherPcdArray   = []\r
+        for Pcd in self._DynamicPcdList:\r
+            # just pick the a value to determine whether is unicode string type\r
+            Sku      = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]\r
+            PcdValue = Sku.DefaultValue\r
+            if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):\r
+                # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex\r
+                UnicodePcdArray.append(Pcd)\r
+            elif len(Sku.VariableName) > 0:\r
+                # if found HII type PCD then insert to right of UnicodeIndex\r
+                HiiPcdArray.append(Pcd)\r
+            else:\r
+                OtherPcdArray.append(Pcd)\r
+        del self._DynamicPcdList[:]\r
+        self._DynamicPcdList.extend(UnicodePcdArray)\r
+        self._DynamicPcdList.extend(HiiPcdArray)\r
+        self._DynamicPcdList.extend(OtherPcdArray)\r
+            \r
+        \r
+    ## Return the platform build data object\r
+    def _GetPlatform(self):\r
+        if self._Platform == None:\r
+            self._Platform = self.BuildDatabase[self.MetaFile, self.Arch]\r
+        return self._Platform\r
+\r
+    ## Return platform name\r
+    def _GetName(self):\r
+        return self.Platform.PlatformName\r
+\r
+    ## Return the meta file GUID\r
+    def _GetGuid(self):\r
+        return self.Platform.Guid\r
+\r
+    ## Return the platform version\r
+    def _GetVersion(self):\r
+        return self.Platform.Version\r
+\r
+    ## Return the FDF file name\r
+    def _GetFdfFile(self):\r
+        if self._FdfFile == None:\r
+            if self.Workspace.FdfFile != "":\r
+                self._FdfFile= path.join(self.WorkspaceDir, self.Workspace.FdfFile)\r
+            else:\r
+                self._FdfFile = ''\r
+        return self._FdfFile\r
+\r
+    ## Return the build output directory platform specifies\r
+    def _GetOutputDir(self):\r
+        return self.Platform.OutputDirectory\r
+\r
+    ## Return the directory to store all intermediate and final files built\r
+    def _GetBuildDir(self):\r
+        if self._BuildDir == None:\r
+            if os.path.isabs(self.OutputDir):\r
+                self._BuildDir = path.join(\r
+                                            path.abspath(self.OutputDir),\r
+                                            self.BuildTarget + "_" + self.ToolChain,\r
+                                            )\r
+            else:\r
+                self._BuildDir = path.join(\r
+                                            self.WorkspaceDir,\r
+                                            self.OutputDir,\r
+                                            self.BuildTarget + "_" + self.ToolChain,\r
+                                            )\r
+        return self._BuildDir\r
+\r
+    ## Return directory of platform makefile\r
+    #\r
+    #   @retval     string  Makefile directory\r
+    #\r
+    def _GetMakeFileDir(self):\r
+        if self._MakeFileDir == None:\r
+            self._MakeFileDir = path.join(self.BuildDir, self.Arch)\r
+        return self._MakeFileDir\r
+\r
+    ## Return build command string\r
+    #\r
+    #   @retval     string  Build command string\r
+    #\r
+    def _GetBuildCommand(self):\r
+        if self._BuildCommand == None:\r
+            self._BuildCommand = []\r
+            if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:\r
+                self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"])\r
+                if "FLAGS" in self.ToolDefinition["MAKE"]:\r
+                    NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip()\r
+                    if NewOption != '':\r
+                      self._BuildCommand += SplitOption(NewOption)\r
+        return self._BuildCommand\r
+\r
+    ## Get tool chain definition\r
+    #\r
+    #  Get each tool defition for given tool chain from tools_def.txt and platform\r
+    #\r
+    def _GetToolDefinition(self):\r
+        if self._ToolDefinitions == None:\r
+            ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary\r
+            if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase:\r
+                EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration",\r
+                                ExtraData="[%s]" % self.MetaFile)\r
+            self._ToolDefinitions = {}\r
+            DllPathList = set()\r
+            for Def in ToolDefinition:\r
+                Target, Tag, Arch, Tool, Attr = Def.split("_")\r
+                if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:\r
+                    continue\r
+\r
+                Value = ToolDefinition[Def]\r
+                # don't record the DLL\r
+                if Attr == "DLL":\r
+                    DllPathList.add(Value)\r
+                    continue\r
+\r
+                if Tool not in self._ToolDefinitions:\r
+                    self._ToolDefinitions[Tool] = {}\r
+                self._ToolDefinitions[Tool][Attr] = Value\r
+\r
+            ToolsDef = ''\r
+            MakePath = ''\r
+            if GlobalData.gOptions.SilentMode and "MAKE" in self._ToolDefinitions:\r
+                if "FLAGS" not in self._ToolDefinitions["MAKE"]:\r
+                    self._ToolDefinitions["MAKE"]["FLAGS"] = ""\r
+                self._ToolDefinitions["MAKE"]["FLAGS"] += " -s"\r
+            MakeFlags = ''\r
+            for Tool in self._ToolDefinitions:\r
+                for Attr in self._ToolDefinitions[Tool]:\r
+                    Value = self._ToolDefinitions[Tool][Attr]\r
+                    if Tool in self.BuildOption and Attr in self.BuildOption[Tool]:\r
+                        # check if override is indicated\r
+                        if self.BuildOption[Tool][Attr].startswith('='):\r
+                            Value = self.BuildOption[Tool][Attr][1:]\r
+                        else:\r
+                            Value += " " + self.BuildOption[Tool][Attr]\r
+\r
+                    if Attr == "PATH":\r
+                        # Don't put MAKE definition in the file\r
+                        if Tool == "MAKE":\r
+                            MakePath = Value\r
+                        else:\r
+                            ToolsDef += "%s = %s\n" % (Tool, Value)\r
+                    elif Attr != "DLL":\r
+                        # Don't put MAKE definition in the file\r
+                        if Tool == "MAKE":\r
+                            if Attr == "FLAGS":\r
+                                MakeFlags = Value\r
+                        else:\r
+                            ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)\r
+                ToolsDef += "\n"\r
+\r
+            SaveFileOnChange(self.ToolDefinitionFile, ToolsDef)\r
+            for DllPath in DllPathList:\r
+                os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"]\r
+            os.environ["MAKE_FLAGS"] = MakeFlags\r
+\r
+        return self._ToolDefinitions\r
+\r
+    ## Return the paths of tools\r
+    def _GetToolDefFile(self):\r
+        if self._ToolDefFile == None:\r
+            self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch)\r
+        return self._ToolDefFile\r
+\r
+    ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.\r
+    def _GetToolChainFamily(self):\r
+        if self._ToolChainFamily == None:\r
+            ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase\r
+            if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \\r
+               or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \\r
+               or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]:\r
+                EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \\r
+                                   % self.ToolChain)\r
+                self._ToolChainFamily = "MSFT"\r
+            else:\r
+                self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]\r
+        return self._ToolChainFamily\r
+\r
+    def _GetBuildRuleFamily(self):\r
+        if self._BuildRuleFamily == None:\r
+            ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase\r
+            if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \\r
+               or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \\r
+               or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]:\r
+                EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \\r
+                                   % self.ToolChain)\r
+                self._BuildRuleFamily = "MSFT"\r
+            else:\r
+                self._BuildRuleFamily = ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]\r
+        return self._BuildRuleFamily\r
+\r
+    ## Return the build options specific to this platform\r
+    def _GetBuildOptions(self):\r
+        if self._BuildOption == None:\r
+            self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)\r
+        return self._BuildOption\r
+\r
+    ## 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 = None\r
+            if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary:\r
+                BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
+            if BuildRuleFile in [None, '']:\r
+                BuildRuleFile = gBuildRuleFile\r
+            self._BuildRule = BuildRule(BuildRuleFile)\r
+        return self._BuildRule\r
+\r
+    ## Summarize the packages used by modules in this platform\r
+    def _GetPackageList(self):\r
+        if self._PackageList == None:\r
+            self._PackageList = set()\r
+            for La in self.LibraryAutoGenList:\r
+                self._PackageList.update(La.DependentPackageList)\r
+            for Ma in self.ModuleAutoGenList:\r
+                self._PackageList.update(Ma.DependentPackageList)\r
+            self._PackageList = list(self._PackageList)\r
+        return self._PackageList\r
+\r
+    ## Get list of non-dynamic PCDs\r
+    def _GetNonDynamicPcdList(self):\r
+        return self._NonDynamicPcdList\r
+\r
+    ## Get list of dynamic PCDs\r
+    def _GetDynamicPcdList(self):\r
+        return self._DynamicPcdList\r
+\r
+    ## Generate Token Number for all PCD\r
+    def _GetPcdTokenNumbers(self):\r
+        if self._PcdTokenNumber == None:\r
+            self._PcdTokenNumber = sdict()\r
+            TokenNumber = 1\r
+            for Pcd in self.DynamicPcdList:\r
+                if Pcd.Phase == "PEI":\r
+                    EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
+                    self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
+                    TokenNumber += 1\r
+\r
+            for Pcd in self.DynamicPcdList:\r
+                if Pcd.Phase == "DXE":\r
+                    EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
+                    self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
+                    TokenNumber += 1\r
+\r
+            for Pcd in self.NonDynamicPcdList:\r
+                self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
+                TokenNumber += 1\r
+        return self._PcdTokenNumber\r
+\r
+    ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform\r
+    def _GetAutoGenObjectList(self):\r
+        self._ModuleAutoGenList = []\r
+        self._LibraryAutoGenList = []\r
+        for ModuleFile in self.Platform.Modules:\r
+            Ma = ModuleAutoGen(\r
+                    self.Workspace,\r
+                    ModuleFile,\r
+                    self.BuildTarget,\r
+                    self.ToolChain,\r
+                    self.Arch,\r
+                    self.MetaFile\r
+                    )\r
+            if Ma not in self._ModuleAutoGenList:\r
+                self._ModuleAutoGenList.append(Ma)\r
+            for La in Ma.LibraryAutoGenList:\r
+                if La not in self._LibraryAutoGenList:\r
+                    self._LibraryAutoGenList.append(La)\r
+\r
+    ## Summarize ModuleAutoGen objects of all modules to be built for this platform\r
+    def _GetModuleAutoGenList(self):\r
+        if self._ModuleAutoGenList == None:\r
+            self._GetAutoGenObjectList()\r
+        return self._ModuleAutoGenList\r
+\r
+    ## Summarize ModuleAutoGen objects of all libraries to be built for this platform\r
+    def _GetLibraryAutoGenList(self):\r
+        if self._LibraryAutoGenList == None:\r
+            self._GetAutoGenObjectList()\r
+        return self._LibraryAutoGenList\r
+\r
+    ## Test if a module is supported by the platform\r
+    #\r
+    #  An error will be raised directly if the module or its arch is not supported\r
+    #  by the platform or current configuration\r
+    #\r
+    def ValidModule(self, Module):\r
+        return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances\r
+\r
+    ## Resolve the library classes in a module to library instances\r
+    #\r
+    # This method will not only resolve library classes but also sort the library\r
+    # instances according to the dependency-ship.\r
+    #\r
+    #   @param  Module      The module from which the library classes will be resolved\r
+    #\r
+    #   @retval library_list    List of library instances sorted\r
+    #\r
+    def ApplyLibraryInstance(self, Module):\r
+        ModuleType = Module.ModuleType\r
+\r
+        # for overridding library instances with module specific setting\r
+        PlatformModule = self.Platform.Modules[str(Module)]\r
+\r
+        # add forced library instances (specified under LibraryClasses sections)\r
+        for LibraryClass in self.Platform.LibraryClasses.GetKeys():\r
+            if LibraryClass.startswith("NULL"):\r
+                Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass]\r
+\r
+        # add forced library instances (specified in module overrides)\r
+        for LibraryClass in PlatformModule.LibraryClasses:\r
+            if LibraryClass.startswith("NULL"):\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
+                if LibraryClassName not in LibraryInstance:\r
+                    # override library instance for this module\r
+                    if LibraryClassName in PlatformModule.LibraryClasses:\r
+                        LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]\r
+                    else:\r
+                        LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]\r
+                    if LibraryPath == None or LibraryPath == "":\r
+                        LibraryPath = M.LibraryClasses[LibraryClassName]\r
+                        if LibraryPath == None or LibraryPath == "":\r
+                            EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,\r
+                                            "Instance of library class [%s] is not found" % LibraryClassName,\r
+                                            File=self.MetaFile,\r
+                                            ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))\r
+\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 LibraryModule.LibraryClass == None \\r
+                         or len(LibraryModule.LibraryClass) == 0 \\r
+                         or (ModuleType != 'USER_DEFINED'\r
+                             and ModuleType not in LibraryModule.LibraryClass[0].SupModList):\r
+                        # only USER_DEFINED can link against any library instance despite of its 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="consumed by [%s]" % str(Module))\r
+\r
+                    LibraryInstance[LibraryClassName] = LibraryModule\r
+                    LibraryConsumerList.append(LibraryModule)\r
+                    EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))\r
+                else:\r
+                    LibraryModule = LibraryInstance[LibraryClassName]\r
+\r
+                if LibraryModule == None:\r
+                    continue\r
+\r
+                if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:\r
+                    Constructor.append(LibraryModule)\r
+\r
+                if LibraryModule not in ConsumedByList:\r
+                    ConsumedByList[LibraryModule] = []\r
+                # don't add current module itself to consumer list\r
+                if M != Module:\r
+                    if M in ConsumedByList[LibraryModule]:\r
+                        continue\r
+                    ConsumedByList[LibraryModule].append(M)\r
+        #\r
+        # Initialize the sorted output list to the empty set\r
+        #\r
+        SortedLibraryList = []\r
+        #\r
+        # Q <- Set of all nodes with no incoming edges\r
+        #\r
+        LibraryList = [] #LibraryInstance.values()\r
+        Q = []\r
+        for LibraryClassName in LibraryInstance:\r
+            M = LibraryInstance[LibraryClassName]\r
+            LibraryList.append(M)\r
+            if ConsumedByList[M] == []:\r
+                Q.append(M)\r
+\r
+        #\r
+        # start the  DAG algorithm\r
+        #\r
+        while True:\r
+            EdgeRemoved = True\r
+            while Q == [] and EdgeRemoved:\r
+                EdgeRemoved = False\r
+                # for each node Item with a Constructor\r
+                for Item in LibraryList:\r
+                    if Item not in Constructor:\r
+                        continue\r
+                    # for each Node without a constructor with an edge e from Item to Node\r
+                    for Node in ConsumedByList[Item]:\r
+                        if Node in Constructor:\r
+                            continue\r
+                        # remove edge e from the graph if Node has no constructor\r
+                        ConsumedByList[Item].remove(Node)\r
+                        EdgeRemoved = True\r
+                        if ConsumedByList[Item] == []:\r
+                            # insert Item into Q\r
+                            Q.insert(0, Item)\r
+                            break\r
+                    if Q != []:\r
+                        break\r
+            # DAG is done if there's no more incoming edge for all nodes\r
+            if Q == []:\r
+                break\r
+\r
+            # remove node from Q\r
+            Node = Q.pop()\r
+            # output Node\r
+            SortedLibraryList.append(Node)\r
+\r
+            # for each node Item with an edge e from Node to Item do\r
+            for Item in LibraryList:\r
+                if Node not in ConsumedByList[Item]:\r
+                    continue\r
+                # remove edge e from the graph\r
+                ConsumedByList[Item].remove(Node)\r
+\r
+                if ConsumedByList[Item] != []:\r
+                    continue\r
+                # insert Item into Q, if Item has no other incoming edges\r
+                Q.insert(0, Item)\r
+\r
+        #\r
+        # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle\r
+        #\r
+        for Item in LibraryList:\r
+            if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:\r
+                ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])\r
+                EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),\r
+                                ExtraData=ErrorMessage, File=self.MetaFile)\r
+            if Item not in SortedLibraryList:\r
+                SortedLibraryList.append(Item)\r
+\r
+        #\r
+        # Build the list of constructor and destructir names\r
+        # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order\r
+        #\r
+        SortedLibraryList.reverse()\r
+        return SortedLibraryList\r
+\r
+\r
+    ## Override PCD setting (type, value, ...)\r
+    #\r
+    #   @param  ToPcd       The PCD to be overrided\r
+    #   @param  FromPcd     The PCD overrideing from\r
+    #\r
+    def _OverridePcd(self, ToPcd, FromPcd, Module=""):\r
+        #\r
+        # in case there's PCDs coming from FDF file, which have no type given.\r
+        # at this point, ToPcd.Type has the type found from dependent\r
+        # package\r
+        #\r
+        if FromPcd != None:\r
+            if ToPcd.Pending and FromPcd.Type not in [None, '']:\r
+                ToPcd.Type = FromPcd.Type\r
+            elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \\r
+                and ToPcd.Type != FromPcd.Type:\r
+                EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",\r
+                                ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\\r
+                                          % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName,\r
+                                             ToPcd.Type, Module, FromPcd.Type),\r
+                                          File=self.MetaFile)\r
+\r
+            if FromPcd.MaxDatumSize not in [None, '']:\r
+                ToPcd.MaxDatumSize = FromPcd.MaxDatumSize\r
+            if FromPcd.DefaultValue not in [None, '']:\r
+                ToPcd.DefaultValue = FromPcd.DefaultValue\r
+            if FromPcd.TokenValue not in [None, '']:\r
+                ToPcd.TokenValue = FromPcd.TokenValue\r
+            if FromPcd.MaxDatumSize not in [None, '']:\r
+                ToPcd.MaxDatumSize = FromPcd.MaxDatumSize\r
+            if FromPcd.DatumType not in [None, '']:\r
+                ToPcd.DatumType = FromPcd.DatumType\r
+            if FromPcd.SkuInfoList not in [None, '', []]:\r
+                ToPcd.SkuInfoList = FromPcd.SkuInfoList\r
+\r
+            # check the validation of datum\r
+            IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)\r
+            if not IsValid:\r
+                EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,\r
+                                ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))\r
+\r
+        if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:\r
+            EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \\r
+                            % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))\r
+            Value = ToPcd.DefaultValue\r
+            if Value in [None, '']:\r
+                ToPcd.MaxDatumSize = 1\r
+            elif Value[0] == 'L':\r
+                ToPcd.MaxDatumSize = str(len(Value) * 2)\r
+            elif Value[0] == '{':\r
+                ToPcd.MaxDatumSize = str(len(Value.split(',')))\r
+            else:\r
+                ToPcd.MaxDatumSize = str(len(Value))\r
+\r
+        # apply default SKU for dynamic PCDS if specified one is not available\r
+        if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \\r
+            and ToPcd.SkuInfoList in [None, {}, '']:\r
+            if self.Platform.SkuName in self.Platform.SkuIds:\r
+                SkuName = self.Platform.SkuName\r
+            else:\r
+                SkuName = 'DEFAULT'\r
+            ToPcd.SkuInfoList = {\r
+                SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue)\r
+            }\r
+\r
+    ## Apply PCD setting defined platform to a module\r
+    #\r
+    #   @param  Module  The module from which the PCD setting will be overrided\r
+    #\r
+    #   @retval PCD_list    The list PCDs with settings from platform\r
+    #\r
+    def ApplyPcdSetting(self, Module, Pcds):\r
+        # for each PCD in module\r
+        for Name,Guid in Pcds:\r
+            PcdInModule = Pcds[Name,Guid]\r
+            # find out the PCD setting in platform\r
+            if (Name,Guid) in self.Platform.Pcds:\r
+                PcdInPlatform = self.Platform.Pcds[Name,Guid]\r
+            else:\r
+                PcdInPlatform = None\r
+            # then override the settings if any\r
+            self._OverridePcd(PcdInModule, PcdInPlatform, Module)\r
+            # resolve the VariableGuid value\r
+            for SkuId in PcdInModule.SkuInfoList:\r
+                Sku = PcdInModule.SkuInfoList[SkuId]\r
+                if Sku.VariableGuid == '': continue\r
+                Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList)\r
+                if Sku.VariableGuidValue == None:\r
+                    PackageList = "\n\t".join([str(P) for P in self.PackageList])\r
+                    EdkLogger.error(\r
+                                'build',\r
+                                RESOURCE_NOT_AVAILABLE,\r
+                                "Value of GUID [%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 Pcds:\r
+                    self._OverridePcd(Pcds[Key], PlatformModule.Pcds[Key], Module)\r
+        return Pcds.values()\r
+\r
+    ## Resolve library names to library modules\r
+    #\r
+    # (for R8.x modules)\r
+    #\r
+    #   @param  Module  The module from which the library names will be resolved\r
+    #\r
+    #   @retval library_list    The list of library modules\r
+    #\r
+    def ResolveLibraryReference(self, Module):\r
+        EdkLogger.verbose("")\r
+        EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
+        LibraryConsumerList = [Module]\r
+\r
+        # "CompilerStub" is a must for R8 modules\r
+        if Module.Libraries:\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
+                    for Key in self.Platform.LibraryClasses.data.keys():\r
+                        if LibraryName.upper() == Key.upper():\r
+                            Library = self.Platform.LibraryClasses[Key, ':dummy:']\r
+                            break\r
+                    if Library == None:\r
+                        EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),\r
+                            ExtraData="\t%s [%s]" % (str(Module), self.Arch))\r
+                        continue\r
+\r
+                if Library not in LibraryList:\r
+                    LibraryList.append(Library)\r
+                    LibraryConsumerList.append(Library)\r
+                    EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library)))\r
+        return LibraryList\r
+\r
+    ## Expand * in build option key\r
+    #\r
+    #   @param  Options     Options to be expanded\r
+    #\r
+    #   @retval options     Options expanded\r
+    #\r
+    def _ExpandBuildOption(self, Options):\r
+        BuildOptions = {}\r
+        FamilyMatch  = False\r
+        FamilyIsNull = True\r
+        for Key in Options:\r
+            Family = Key[0]\r
+            Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
+            # if tool chain family doesn't match, skip it\r
+            if Tool in self.ToolDefinition and Family != "":\r
+                FamilyIsNull = False\r
+                if self.ToolDefinition[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":\r
+                    if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
+                        continue\r
+                elif Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:\r
+                    continue\r
+                FamilyMatch = True\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] = {}\r
+                        if Attr != "FLAGS" or Attr not in BuildOptions[Tool]:\r
+                            BuildOptions[Tool][Attr] = Options[Key]\r
+                        else:\r
+                            # append options for the same tool\r
+                            BuildOptions[Tool][Attr] += " " + Options[Key]\r
+        # Build Option Family has been checked, which need't to be checked again for family.\r
+        if FamilyMatch or FamilyIsNull:\r
+            return BuildOptions\r
+        \r
+        for Key in Options:\r
+            Family = Key[0]\r
+            Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
+            # if tool chain family doesn't match, skip it\r
+            if Tool not in self.ToolDefinition or Family =="":\r
+                continue\r
+            # option has been added before\r
+            if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:\r
+                continue\r
+\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] = {}\r
+                        if Attr != "FLAGS" or Attr not in BuildOptions[Tool]:\r
+                            BuildOptions[Tool][Attr] = Options[Key]\r
+                        else:\r
+                            # append options for the same tool\r
+                            BuildOptions[Tool][Attr] += " " + Options[Key]\r
+        return BuildOptions\r
+\r
+    ## Append build options in platform to a module\r
+    #\r
+    #   @param  Module  The module to which the build options will be appened\r
+    #\r
+    #   @retval options     The options appended with build options in platform\r
+    #\r
+    def ApplyBuildOption(self, Module):\r
+        PlatformOptions = self.BuildOption\r
+        ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)\r
+        if Module in self.Platform.Modules:\r
+            PlatformModule = self.Platform.Modules[str(Module)]\r
+            PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)\r
+        else:\r
+            PlatformModuleOptions = {}\r
+\r
+        AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() + PlatformModuleOptions.keys() + self.ToolDefinition.keys())\r
+        BuildOptions = {}\r
+        for Tool in AllTools:\r
+            if Tool not in BuildOptions:\r
+                BuildOptions[Tool] = {}\r
+\r
+            for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, PlatformModuleOptions]:\r
+                if Tool not in Options:\r
+                    continue\r
+                for Attr in Options[Tool]:\r
+                    Value = Options[Tool][Attr]\r
+                    if Attr not in BuildOptions[Tool]:\r
+                        BuildOptions[Tool][Attr] = ""\r
+                    # check if override is indicated\r
+                    if Value.startswith('='):\r
+                        BuildOptions[Tool][Attr] = Value[1:]\r
+                    else:\r
+                        BuildOptions[Tool][Attr] += " " + Value\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
+    ToolDefinition      = property(_GetToolDefinition)    # toolcode : tool path\r
+    ToolDefinitionFile  = property(_GetToolDefFile)    # toolcode : lib path\r
+    ToolChainFamily     = property(_GetToolChainFamily)\r
+    BuildRuleFamily     = property(_GetBuildRuleFamily)\r
+    BuildOption         = property(_GetBuildOptions)    # toolcode : option\r
+\r
+    BuildCommand        = property(_GetBuildCommand)\r
+    BuildRule           = property(_GetBuildRule)\r
+    ModuleAutoGenList   = property(_GetModuleAutoGenList)\r
+    LibraryAutoGenList  = property(_GetLibraryAutoGenList)\r
+\r
+## ModuleAutoGen class\r
+#\r
+# This class encapsules the AutoGen behaviors for the build tools. In addition to\r
+# the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according\r
+# to the [depex] section in module's inf file.\r
+#\r
+class ModuleAutoGen(AutoGen):\r
+    ## The real constructor of ModuleAutoGen\r
+    #\r
+    #  This method is not supposed to be called by users of ModuleAutoGen. It's\r
+    #  only used by factory method __new__() to do real initialization work for an\r
+    #  object of ModuleAutoGen\r
+    #\r
+    #   @param      Workspace           EdkIIWorkspaceBuild object\r
+    #   @param      ModuleFile          The path of module file\r
+    #   @param      Target              Build target (DEBUG, RELEASE)\r
+    #   @param      Toolchain           Name of tool chain\r
+    #   @param      Arch                The arch the module supports\r
+    #   @param      PlatformFile        Platform meta-file\r
+    #\r
+    def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):\r
+        EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch))\r
+        GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target)\r
+\r
+        self.Workspace = Workspace\r
+        self.WorkspaceDir = Workspace.WorkspaceDir\r
+\r
+        self.MetaFile = ModuleFile\r
+        self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)\r
+        # check if this module is employed by active platform\r
+        if not self.PlatformInfo.ValidModule(self.MetaFile):\r
+            EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \\r
+                              % (self.MetaFile, Arch))\r
+            return False\r
+\r
+        self.SourceDir = self.MetaFile.SubDir\r
+        self.SourceOverrideDir = None\r
+        # use overrided path defined in DSC file\r
+        if self.MetaFile.Key in GlobalData.gOverrideDir:\r
+            self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key]\r
+\r
+        self.ToolChain = Toolchain\r
+        self.BuildTarget = Target\r
+        self.Arch = Arch\r
+        self.ToolChainFamily = self.PlatformInfo.ToolChainFamily\r
+        self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily\r
+\r
+        self.IsMakeFileCreated = False\r
+        self.IsCodeFileCreated = False\r
+\r
+        self.BuildDatabase = self.Workspace.BuildDatabase\r
+\r
+        self._Module          = None\r
+        self._Name            = None\r
+        self._Guid            = None\r
+        self._Version         = None\r
+        self._ModuleType      = None\r
+        self._ComponentType   = None\r
+        self._PcdIsDriver     = None\r
+        self._AutoGenVersion  = None\r
+        self._LibraryFlag     = None\r
+        self._CustomMakefile  = None\r
+        self._Macro           = None\r
+\r
+        self._BuildDir        = None\r
+        self._OutputDir       = None\r
+        self._DebugDir        = None\r
+        self._MakeFileDir     = None\r
+\r
+        self._IncludePathList = None\r
+        self._AutoGenFileList = None\r
+        self._UnicodeFileList = None\r
+        self._SourceFileList  = None\r
+        self._ObjectFileList  = None\r
+        self._BinaryFileList  = None\r
+\r
+        self._DependentPackageList    = None\r
+        self._DependentLibraryList    = None\r
+        self._LibraryAutoGenList      = None\r
+        self._DerivedPackageList      = None\r
+        self._ModulePcdList           = None\r
+        self._LibraryPcdList          = None\r
+        self._GuidList                = None\r
+        self._ProtocolList            = None\r
+        self._PpiList                 = None\r
+        self._DepexList               = None\r
+        self._DepexExpressionList     = None\r
+        self._BuildOption             = None\r
+        self._BuildTargets            = None\r
+        self._IntroBuildTargetList    = None\r
+        self._FinalBuildTargetList    = None\r
+        self._FileTypes               = None\r
+        self._BuildRules              = None\r
+\r
+        return True\r
+\r
+    def __repr__(self):\r
+        return "%s [%s]" % (self.MetaFile, self.Arch)\r
+\r
+    # Macros could be used in build_rule.txt (also Makefile)\r
+    def _GetMacros(self):\r
+        if self._Macro == None:\r
+            self._Macro = sdict()\r
+            self._Macro["WORKSPACE"             ] = self.WorkspaceDir\r
+            self._Macro["MODULE_NAME"           ] = self.Name\r
+            self._Macro["MODULE_GUID"           ] = self.Guid\r
+            self._Macro["MODULE_VERSION"        ] = self.Version\r
+            self._Macro["MODULE_TYPE"           ] = self.ModuleType\r
+            self._Macro["MODULE_FILE"           ] = str(self.MetaFile)\r
+            self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName\r
+            self._Macro["MODULE_RELATIVE_DIR"   ] = self.SourceDir\r
+            self._Macro["MODULE_DIR"            ] = self.SourceDir\r
+\r
+            self._Macro["BASE_NAME"             ] = self.Name\r
+\r
+            self._Macro["ARCH"                  ] = self.Arch\r
+            self._Macro["TOOLCHAIN"             ] = self.ToolChain\r
+            self._Macro["TOOLCHAIN_TAG"         ] = self.ToolChain\r
+            self._Macro["TARGET"                ] = self.BuildTarget\r
+\r
+            self._Macro["BUILD_DIR"             ] = self.PlatformInfo.BuildDir\r
+            self._Macro["BIN_DIR"               ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)\r
+            self._Macro["LIB_DIR"               ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)\r
+            self._Macro["MODULE_BUILD_DIR"      ] = self.BuildDir\r
+            self._Macro["OUTPUT_DIR"            ] = self.OutputDir\r
+            self._Macro["DEBUG_DIR"             ] = self.DebugDir\r
+        return self._Macro\r
+\r
+    ## Return the module build data object\r
+    def _GetModule(self):\r
+        if self._Module == None:\r
+            self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch]\r
+        return self._Module\r
+\r
+    ## Return the module name\r
+    def _GetBaseName(self):\r
+        return self.Module.BaseName\r
+\r
+    ## Return the module SourceOverridePath\r
+    def _GetSourceOverridePath(self):\r
+        return self.Module.SourceOverridePath\r
+\r
+    ## Return the module meta-file GUID\r
+    def _GetGuid(self):\r
+        return self.Module.Guid\r
+\r
+    ## Return the module version\r
+    def _GetVersion(self):\r
+        return self.Module.Version\r
+\r
+    ## Return the module type\r
+    def _GetModuleType(self):\r
+        return self.Module.ModuleType\r
+\r
+    ## Return the component type (for R8.x style of module)\r
+    def _GetComponentType(self):\r
+        return self.Module.ComponentType\r
+\r
+    ## Return the build type\r
+    def _GetBuildType(self):\r
+        return self.Module.BuildType\r
+\r
+    ## Return the PCD_IS_DRIVER setting\r
+    def _GetPcdIsDriver(self):\r
+        return self.Module.PcdIsDriver\r
+\r
+    ## Return the autogen version, i.e. module meta-file version\r
+    def _GetAutoGenVersion(self):\r
+        return self.Module.AutoGenVersion\r
+\r
+    ## Check if the module is library or not\r
+    def _IsLibrary(self):\r
+        if self._LibraryFlag == None:\r
+            if self.Module.LibraryClass != None and self.Module.LibraryClass != []:\r
+                self._LibraryFlag = True\r
+            else:\r
+                self._LibraryFlag = False\r
+        return self._LibraryFlag\r
+\r
+    ## Return the directory to store intermediate files of the module\r
+    def _GetBuildDir(self):\r
+        if self._BuildDir == None:\r
+            self._BuildDir = path.join(\r
+                                    self.PlatformInfo.BuildDir,\r
+                                    self.Arch,\r
+                                    self.SourceDir,\r
+                                    self.MetaFile.BaseName\r
+                                    )\r
+            CreateDirectory(self._BuildDir)\r
+        return self._BuildDir\r
+\r
+    ## Return the directory to store the intermediate object files of the mdoule\r
+    def _GetOutputDir(self):\r
+        if self._OutputDir == None:\r
+            self._OutputDir = path.join(self.BuildDir, "OUTPUT")\r
+            CreateDirectory(self._OutputDir)\r
+        return self._OutputDir\r
+\r
+    ## Return the directory to store auto-gened source files of the mdoule\r
+    def _GetDebugDir(self):\r
+        if self._DebugDir == None:\r
+            self._DebugDir = path.join(self.BuildDir, "DEBUG")\r
+            CreateDirectory(self._DebugDir)\r
+        return self._DebugDir\r
+\r
+    ## Return the path of custom file\r
+    def _GetCustomMakefile(self):\r
+        if self._CustomMakefile == None:\r
+            self._CustomMakefile = {}\r
+            for Type in self.Module.CustomMakefile:\r
+                if Type in gMakeTypeMap:\r
+                    MakeType = gMakeTypeMap[Type]\r
+                else:\r
+                    MakeType = 'nmake'\r
+                if self.SourceOverrideDir != None:\r
+                    File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type])\r
+                    if not os.path.exists(File):\r
+                        File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])\r
+                else:\r
+                    File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])\r
+                self._CustomMakefile[MakeType] = File\r
+        return self._CustomMakefile\r
+\r
+    ## Return the directory of the makefile\r
+    #\r
+    #   @retval     string  The directory string of module's makefile\r
+    #\r
+    def _GetMakeFileDir(self):\r
+        return self.BuildDir\r
+\r
+    ## Return build command string\r
+    #\r
+    #   @retval     string  Build command string\r
+    #\r
+    def _GetBuildCommand(self):\r
+        return self.PlatformInfo.BuildCommand\r
+\r
+    ## Get object list of all packages the module and its dependent libraries belong to\r
+    #\r
+    #   @retval     list    The list of package object\r
+    #\r
+    def _GetDerivedPackageList(self):\r
+        PackageList = []\r
+        for M in [self.Module] + self.DependentLibraryList:\r
+            for Package in M.Packages:\r
+                if Package in PackageList:\r
+                    continue\r
+                PackageList.append(Package)\r
+        return PackageList\r
+\r
+    ## Merge dependency expression\r
+    #\r
+    #   @retval     list    The token list of the dependency expression after parsed\r
+    #\r
+    def _GetDepexTokenList(self):\r
+        if self._DepexList == None:\r
+            self._DepexList = {}\r
+            if self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:\r
+                return self._DepexList\r
+\r
+            self._DepexList[self.ModuleType] = []\r
+\r
+            for ModuleType in self._DepexList:\r
+                DepexList = self._DepexList[ModuleType]\r
+                #\r
+                # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion\r
+                #\r
+                for M in [self.Module] + self.DependentLibraryList:\r
+                    Inherited = False\r
+                    for D in M.Depex[self.Arch, ModuleType]:\r
+                        if DepexList != []:\r
+                            DepexList.append('AND')\r
+                        DepexList.append('(')\r
+                        DepexList.extend(D)\r
+                        if DepexList[-1] == 'END':  # no need of a END at this time\r
+                            DepexList.pop()\r
+                        DepexList.append(')')\r
+                        Inherited = True\r
+                    if Inherited:\r
+                        EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexList))\r
+                    if 'BEFORE' in DepexList or 'AFTER' in DepexList:\r
+                        break\r
+                if len(DepexList) > 0:\r
+                    EdkLogger.verbose('')\r
+        return self._DepexList\r
+\r
+    ## Merge dependency expression\r
+    #\r
+    #   @retval     list    The token list of the dependency expression after parsed\r
+    #\r
+    def _GetDepexExpressionTokenList(self):\r
+        if self._DepexExpressionList == None:\r
+            self._DepexExpressionList = {}\r
+            if self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:\r
+                return self._DepexExpressionList\r
+\r
+            self._DepexExpressionList[self.ModuleType] = ''\r
+\r
+            for ModuleType in self._DepexExpressionList:\r
+                DepexExpressionList = self._DepexExpressionList[ModuleType]\r
+                #\r
+                # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion\r
+                #\r
+                for M in [self.Module] + self.DependentLibraryList:\r
+                    Inherited = False\r
+                    for D in M.DepexExpression[self.Arch, ModuleType]:\r
+                        if DepexExpressionList != '':\r
+                            DepexExpressionList += ' AND '\r
+                        DepexExpressionList += '('\r
+                        DepexExpressionList += D\r
+                        DepexExpressionList = DepexExpressionList.rstrip('END').strip()\r
+                        DepexExpressionList += ')'\r
+                        Inherited = True\r
+                    if Inherited:\r
+                        EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexExpressionList))\r
+                    if 'BEFORE' in DepexExpressionList or 'AFTER' in DepexExpressionList:\r
+                        break\r
+                if len(DepexExpressionList) > 0:\r
+                    EdkLogger.verbose('')\r
+                self._DepexExpressionList[ModuleType] = DepexExpressionList\r
+        return self._DepexExpressionList\r
+\r
+    ## Return the list of specification version required for the module\r
+    #\r
+    #   @retval     list    The list of specification defined in module file\r
+    #\r
+    def _GetSpecification(self):\r
+        return self.Module.Specification\r
+\r
+    ## Tool option for the module build\r
+    #\r
+    #   @param      PlatformInfo    The object of PlatformBuildInfo\r
+    #   @retval     dict            The dict containing valid options\r
+    #\r
+    def _GetModuleBuildOption(self):\r
+        if self._BuildOption == None:\r
+            self._BuildOption = self.PlatformInfo.ApplyBuildOption(self.Module)\r
+        return self._BuildOption\r
+\r
+    ## Return a list of files which can be built from source\r
+    #\r
+    #  What kind of files can be built is determined by build rules in\r
+    #  $(WORKSPACE)/Conf/build_rule.txt and toolchain family.\r
+    #\r
+    def _GetSourceFileList(self):\r
+        if self._SourceFileList == None:\r
+            self._SourceFileList = []\r
+            for F in self.Module.Sources:\r
+                # match tool chain\r
+                if F.TagName != "" and F.TagName != self.ToolChain:\r
+                    EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, "\r
+                                    "but [%s] is needed" % (F.TagName, str(F), self.ToolChain))\r
+                    continue\r
+                # match tool chain family\r
+                if F.ToolChainFamily != "" and F.ToolChainFamily != self.ToolChainFamily:\r
+                    EdkLogger.debug(\r
+                                EdkLogger.DEBUG_0,\r
+                                "The file [%s] must be built by tools of [%s], " \\r
+                                "but current toolchain family is [%s]" \\r
+                                    % (str(F), F.ToolChainFamily, self.ToolChainFamily))\r
+                    continue\r
+\r
+                # add the file path into search path list for file including\r
+                if F.Dir not in self.IncludePathList and self.AutoGenVersion >= 0x00010005:\r
+                    self.IncludePathList.insert(0, F.Dir)\r
+                self._SourceFileList.append(F)\r
+                self._ApplyBuildRule(F, TAB_UNKNOWN_FILE)\r
+        return self._SourceFileList\r
+\r
+    ## Return the list of unicode files\r
+    def _GetUnicodeFileList(self):\r
+        if self._UnicodeFileList == None:\r
+            if TAB_UNICODE_FILE in self.FileTypes:\r
+                self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE]\r
+            else:\r
+                self._UnicodeFileList = []\r
+        return self._UnicodeFileList\r
+\r
+    ## Return a list of files which can be built from binary\r
+    #\r
+    #  "Build" binary files are just to copy them to build directory.\r
+    #\r
+    #   @retval     list            The list of files which can be built later\r
+    #\r
+    def _GetBinaryFiles(self):\r
+        if self._BinaryFileList == None:\r
+            self._BinaryFileList = []\r
+            for F in self.Module.Binaries:\r
+                if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget:\r
+                    continue\r
+                self._BinaryFileList.append(F)\r
+                self._ApplyBuildRule(F, F.Type)\r
+        return self._BinaryFileList\r
+\r
+    def _GetBuildRules(self):\r
+        if self._BuildRules == None:\r
+            BuildRules = {}\r
+            BuildRuleDatabase = self.PlatformInfo.BuildRule\r
+            for Type in BuildRuleDatabase.FileTypeList:\r
+                #first try getting build rule by BuildRuleFamily\r
+                RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.BuildRuleFamily]\r
+                if not RuleObject:\r
+                    # build type is always module type, but ...\r
+                    if self.ModuleType != self.BuildType:\r
+                        RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.BuildRuleFamily]\r
+                #second try getting build rule by ToolChainFamily\r
+                if not RuleObject:\r
+                    RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.ToolChainFamily]\r
+                    if not RuleObject:\r
+                        # build type is always module type, but ...\r
+                        if self.ModuleType != self.BuildType:\r
+                            RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.ToolChainFamily]\r
+                if not RuleObject:\r
+                    continue\r
+                RuleObject = RuleObject.Instantiate(self.Macros)\r
+                BuildRules[Type] = RuleObject\r
+                for Ext in RuleObject.SourceFileExtList:\r
+                    BuildRules[Ext] = RuleObject\r
+            self._BuildRules = BuildRules\r
+        return self._BuildRules\r
+\r
+    def _ApplyBuildRule(self, File, FileType):\r
+        if self._BuildTargets == None:\r
+            self._IntroBuildTargetList = set()\r
+            self._FinalBuildTargetList = set()\r
+            self._BuildTargets = {}\r
+            self._FileTypes = {}\r
+\r
+        LastTarget = None\r
+        RuleChain = []\r
+        SourceList = [File]\r
+        Index = 0\r
+        while Index < len(SourceList):\r
+            Source = SourceList[Index]\r
+            Index = Index + 1\r
+\r
+            if Source != File:\r
+                CreateDirectory(Source.Dir)\r
+\r
+            if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._BinaryFileList:\r
+                RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]\r
+            elif FileType in self.BuildRules:\r
+                RuleObject = self.BuildRules[FileType]\r
+            elif Source.Ext in self.BuildRules:\r
+                RuleObject = self.BuildRules[Source.Ext]\r
+            else:\r
+                # stop at no more rules\r
+                if LastTarget:\r
+                    self._FinalBuildTargetList.add(LastTarget)\r
+                break\r
+\r
+            FileType = RuleObject.SourceFileType\r
+            if FileType not in self._FileTypes:\r
+                self._FileTypes[FileType] = set()\r
+            self._FileTypes[FileType].add(Source)\r
+\r
+            # stop at STATIC_LIBRARY for library\r
+            if self.IsLibrary and FileType == TAB_STATIC_LIBRARY:\r
+                if LastTarget:\r
+                    self._FinalBuildTargetList.add(LastTarget)\r
+                break\r
+\r
+            Target = RuleObject.Apply(Source)\r
+            if not Target:\r
+                if LastTarget:\r
+                    self._FinalBuildTargetList.add(LastTarget)\r
+                break\r
+            elif not Target.Outputs:\r
+                # Only do build for target with outputs\r
+                self._FinalBuildTargetList.add(Target)\r
+\r
+            if FileType not in self._BuildTargets:\r
+                self._BuildTargets[FileType] = set()\r
+            self._BuildTargets[FileType].add(Target)\r
+\r
+            if not Source.IsBinary and Source == File:\r
+                self._IntroBuildTargetList.add(Target)\r
+\r
+            # to avoid cyclic rule\r
+            if FileType in RuleChain:\r
+                break\r
+\r
+            RuleChain.append(FileType)\r
+            SourceList.extend(Target.Outputs)\r
+            LastTarget = Target\r
+            FileType = TAB_UNKNOWN_FILE\r
+\r
+    def _GetTargets(self):\r
+        if self._BuildTargets == None:\r
+            self._IntroBuildTargetList = set()\r
+            self._FinalBuildTargetList = set()\r
+            self._BuildTargets = {}\r
+            self._FileTypes = {}\r
+\r
+        #TRICK: call _GetSourceFileList to apply build rule for binary files\r
+        if self.SourceFileList:\r
+            pass\r
+\r
+        #TRICK: call _GetBinaryFileList to apply build rule for binary files\r
+        if self.BinaryFileList:\r
+            pass\r
+\r
+        return self._BuildTargets\r
+\r
+    def _GetIntroTargetList(self):\r
+        self._GetTargets()\r
+        return self._IntroBuildTargetList\r
+\r
+    def _GetFinalTargetList(self):\r
+        self._GetTargets()\r
+        return self._FinalBuildTargetList\r
+\r
+    def _GetFileTypes(self):\r
+        self._GetTargets()\r
+        return self._FileTypes\r
+\r
+    ## Get the list of package object the module depends on\r
+    #\r
+    #   @retval     list    The package object list\r
+    #\r
+    def _GetDependentPackageList(self):\r
+        return self.Module.Packages\r
+\r
+    ## Return the list of auto-generated code file\r
+    #\r
+    #   @retval     list        The list of auto-generated file\r
+    #\r
+    def _GetAutoGenFileList(self):\r
+        UniStringAutoGenC = True\r
+        UniStringBinBuffer = None\r
+        if self.BuildType == 'UEFI_HII':\r
+            UniStringBinBuffer = StringIO()\r
+            UniStringAutoGenC = False\r
+        if self._AutoGenFileList == None:\r
+            self._AutoGenFileList = {}\r
+            AutoGenC = TemplateString()\r
+            AutoGenH = TemplateString()\r
+            StringH = TemplateString()\r
+            GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer)\r
+            if str(AutoGenC) != "" and TAB_C_CODE_FILE in self.FileTypes:\r
+                AutoFile = PathClass(gAutoGenCodeFileName, self.DebugDir)\r
+                self._AutoGenFileList[AutoFile] = str(AutoGenC)\r
+                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
+            if str(AutoGenH) != "":\r
+                AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir)\r
+                self._AutoGenFileList[AutoFile] = str(AutoGenH)\r
+                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
+            if str(StringH) != "":\r
+                AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir)\r
+                self._AutoGenFileList[AutoFile] = str(StringH)\r
+                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
+            if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "":\r
+                AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)\r
+                self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue()\r
+                AutoFile.IsBinary = True\r
+                self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
+            if UniStringBinBuffer != None:\r
+                UniStringBinBuffer.close()\r
+        return self._AutoGenFileList\r
+\r
+    ## Return the list of library modules explicitly or implicityly used by this module\r
+    def _GetLibraryList(self):\r
+        if self._DependentLibraryList == None:\r
+            # only merge library classes and PCD for non-library module\r
+            if self.IsLibrary:\r
+                self._DependentLibraryList = []\r
+            else:\r
+                if self.AutoGenVersion < 0x00010005:\r
+                    self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module)\r
+                else:\r
+                    self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)\r
+        return self._DependentLibraryList\r
+\r
+    ## Get the list of PCDs from current module\r
+    #\r
+    #   @retval     list                    The list of PCD\r
+    #\r
+    def _GetModulePcdList(self):\r
+        if self._ModulePcdList == None:\r
+            # apply PCD settings from platform\r
+            self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)\r
+        return self._ModulePcdList\r
+\r
+    ## Get the list of PCDs from dependent libraries\r
+    #\r
+    #   @retval     list                    The list of PCD\r
+    #\r
+    def _GetLibraryPcdList(self):\r
+        if self._LibraryPcdList == None:\r
+            Pcds = {}\r
+            if not self.IsLibrary:\r
+                # get PCDs from dependent libraries\r
+                for Library in self.DependentLibraryList:\r
+                    for Key in Library.Pcds:\r
+                        # skip duplicated PCDs\r
+                        if Key in self.Module.Pcds or Key in Pcds:\r
+                            continue\r
+                        Pcds[Key] = copy.copy(Library.Pcds[Key])\r
+                # apply PCD settings from platform\r
+                self._LibraryPcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, Pcds)\r
+            else:\r
+                self._LibraryPcdList = []\r
+        return self._LibraryPcdList\r
+\r
+    ## Get the GUID value mapping\r
+    #\r
+    #   @retval     dict    The mapping between GUID cname and its value\r
+    #\r
+    def _GetGuidList(self):\r
+        if self._GuidList == None:\r
+            self._GuidList = self.Module.Guids\r
+            for Library in self.DependentLibraryList:\r
+                self._GuidList.update(Library.Guids)\r
+        return self._GuidList\r
+\r
+    ## Get the protocol value mapping\r
+    #\r
+    #   @retval     dict    The mapping between protocol cname and its value\r
+    #\r
+    def _GetProtocolList(self):\r
+        if self._ProtocolList == None:\r
+            self._ProtocolList = self.Module.Protocols\r
+            for Library in self.DependentLibraryList:\r
+                self._ProtocolList.update(Library.Protocols)\r
+        return self._ProtocolList\r
+\r
+    ## Get the PPI value mapping\r
+    #\r
+    #   @retval     dict    The mapping between PPI cname and its value\r
+    #\r
+    def _GetPpiList(self):\r
+        if self._PpiList == None:\r
+            self._PpiList = self.Module.Ppis\r
+            for Library in self.DependentLibraryList:\r
+                self._PpiList.update(Library.Ppis)\r
+        return self._PpiList\r
+\r
+    ## Get the list of include search path\r
+    #\r
+    #   @retval     list                    The list path\r
+    #\r
+    def _GetIncludePathList(self):\r
+        if self._IncludePathList == None:\r
+            self._IncludePathList = []\r
+            if self.AutoGenVersion < 0x00010005:\r
+                for Inc in self.Module.Includes:\r
+                    if Inc not in self._IncludePathList:\r
+                        self._IncludePathList.append(Inc)\r
+                    # for r8 modules\r
+                    Inc = path.join(Inc, self.Arch.capitalize())\r
+                    if os.path.exists(Inc) and Inc not in self._IncludePathList:\r
+                        self._IncludePathList.append(Inc)\r
+                # r8 module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time\r
+                self._IncludePathList.append(self.DebugDir)\r
+            else:\r
+                self._IncludePathList.append(self.MetaFile.Dir)\r
+                self._IncludePathList.append(self.DebugDir)\r
+\r
+            for Package in self.Module.Packages:\r
+                PackageDir = path.join(self.WorkspaceDir, Package.MetaFile.Dir)\r
+                if PackageDir not in self._IncludePathList:\r
+                    self._IncludePathList.append(PackageDir)\r
+                for Inc in Package.Includes:\r
+                    if Inc not in self._IncludePathList:\r
+                        self._IncludePathList.append(str(Inc))\r
+        return self._IncludePathList\r
+\r
+    ## Create makefile for the module and its dependent libraries\r
+    #\r
+    #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of\r
+    #                                       dependent libraries will be created\r
+    #\r
+    def CreateMakeFile(self, CreateLibraryMakeFile=True):\r
+        if self.IsMakeFileCreated:\r
+            return\r
+\r
+        if not self.IsLibrary and CreateLibraryMakeFile:\r
+            for LibraryAutoGen in self.LibraryAutoGenList:\r
+                LibraryAutoGen.CreateMakeFile()\r
+\r
+        if len(self.CustomMakefile) == 0:\r
+            Makefile = GenMake.ModuleMakefile(self)\r
+        else:\r
+            Makefile = GenMake.CustomMakefile(self)\r
+        if Makefile.Generate():\r
+            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for module %s [%s]" %\r
+                            (self.Name, self.Arch))\r
+        else:\r
+            EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %\r
+                            (self.Name, self.Arch))\r
+\r
+        self.IsMakeFileCreated = True\r
+\r
+    ## Create autogen code for the module and its dependent libraries\r
+    #\r
+    #   @param      CreateLibraryCodeFile   Flag indicating if or not the code of\r
+    #                                       dependent libraries will be created\r
+    #\r
+    def CreateCodeFile(self, CreateLibraryCodeFile=True):\r
+        if self.IsCodeFileCreated:\r
+            return\r
+\r
+        if not self.IsLibrary and CreateLibraryCodeFile:\r
+            for LibraryAutoGen in self.LibraryAutoGenList:\r
+                LibraryAutoGen.CreateCodeFile()\r
+\r
+        AutoGenList = []\r
+        IgoredAutoGenList = []\r
+\r
+        for File in self.AutoGenFileList:\r
+            if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary):\r
+                #Ignore R8 AutoGen.c\r
+                if self.AutoGenVersion < 0x00010005 and File.Name == 'AutoGen.c':\r
+                        continue\r
+\r
+                AutoGenList.append(str(File))\r
+            else:\r
+                IgoredAutoGenList.append(str(File))\r
+\r
+        # Skip the following code for EDK I inf\r
+        if self.AutoGenVersion < 0x00010005:\r
+            return\r
+\r
+        for ModuleType in self.DepexList:\r
+            if len(self.DepexList[ModuleType]) == 0:\r
+                continue\r
+            Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True)\r
+            DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}\r
+\r
+            if Dpx.Generate(path.join(self.OutputDir, DpxFile)):\r
+                AutoGenList.append(str(DpxFile))\r
+            else:\r
+                IgoredAutoGenList.append(str(DpxFile))\r
+\r
+        if IgoredAutoGenList == []:\r
+            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] files for module %s [%s]" %\r
+                            (" ".join(AutoGenList), self.Name, self.Arch))\r
+        elif AutoGenList == []:\r
+            EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of [%s] files for module %s [%s]" %\r
+                            (" ".join(IgoredAutoGenList), self.Name, self.Arch))\r
+        else:\r
+            EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] (skipped %s) files for module %s [%s]" %\r
+                            (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))\r
+\r
+        self.IsCodeFileCreated = True\r
+        return AutoGenList\r
+\r
+    ## Summarize the ModuleAutoGen objects of all libraries used by this module\r
+    def _GetLibraryAutoGenList(self):\r
+        if self._LibraryAutoGenList == None:\r
+            self._LibraryAutoGenList = []\r
+            for Library in self.DependentLibraryList:\r
+                La = ModuleAutoGen(\r
+                        self.Workspace,\r
+                        Library.MetaFile,\r
+                        self.BuildTarget,\r
+                        self.ToolChain,\r
+                        self.Arch,\r
+                        self.PlatformInfo.MetaFile\r
+                        )\r
+                if La not in self._LibraryAutoGenList:\r
+                    self._LibraryAutoGenList.append(La)\r
+                    for Lib in La.CodaTargetList:\r
+                        self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)\r
+        return self._LibraryAutoGenList\r
+\r
+    ## Return build command string\r
+    #\r
+    #   @retval     string  Build command string\r
+    #\r
+    def _GetBuildCommand(self):\r
+        return self.PlatformInfo.BuildCommand\r
+\r
+\r
+    Module          = property(_GetModule)\r
+    Name            = property(_GetBaseName)\r
+    Guid            = property(_GetGuid)\r
+    Version         = property(_GetVersion)\r
+    ModuleType      = property(_GetModuleType)\r
+    ComponentType   = property(_GetComponentType)\r
+    BuildType       = property(_GetBuildType)\r
+    PcdIsDriver     = property(_GetPcdIsDriver)\r
+    AutoGenVersion  = property(_GetAutoGenVersion)\r
+    Macros          = property(_GetMacros)\r
+    Specification   = property(_GetSpecification)\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
+    BinaryFileList  = property(_GetBinaryFiles) # FileType : [File List]\r
+    Targets         = property(_GetTargets)\r
+    IntroTargetList = property(_GetIntroTargetList)\r
+    CodaTargetList  = property(_GetFinalTargetList)\r
+    FileTypes       = property(_GetFileTypes)\r
+    BuildRules      = property(_GetBuildRules)\r
+\r
+    DependentPackageList    = property(_GetDependentPackageList)\r
+    DependentLibraryList    = property(_GetLibraryList)\r
+    LibraryAutoGenList      = property(_GetLibraryAutoGenList)\r
+    DerivedPackageList      = property(_GetDerivedPackageList)\r
+\r
+    ModulePcdList           = property(_GetModulePcdList)\r
+    LibraryPcdList          = property(_GetLibraryPcdList)\r
+    GuidList                = property(_GetGuidList)\r
+    ProtocolList            = property(_GetProtocolList)\r
+    PpiList                 = property(_GetPpiList)\r
+    DepexList               = property(_GetDepexTokenList)\r
+    DepexExpressionList     = property(_GetDepexExpressionTokenList)\r
+    BuildOption             = property(_GetModuleBuildOption)\r
+    BuildCommand            = property(_GetBuildCommand)\r
+\r
+# This acts like the main() function for the script, unless it is 'import'ed into another script.\r
+if __name__ == '__main__':\r
+    pass\r
+\r
diff --git a/Source/Python/build/BuildReport.py b/Source/Python/build/BuildReport.py
new file mode 100755 (executable)
index 0000000..71b9e02
--- /dev/null
@@ -0,0 +1,738 @@
+## @file
+# Routines for generating build report.
+# 
+# This module contains the functionality to generate build report after
+# build all target completes successfully. 
+#
+# Copyright (c) 2010, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+## Import Modules
+#
+import os
+import re
+import platform
+import textwrap
+from Common import EdkLogger
+from Common.BuildToolError import FILE_OPEN_FAILURE
+from Common.BuildToolError import FILE_WRITE_FAILURE
+
+
+## Pattern to extract contents in EDK DXS files
+gDxsDependencyPattern = re.compile(r"DEPENDENCY_START(.+)DEPENDENCY_END", re.DOTALL)
+
+## Pattern to find total FV total size, occupied size in flash report intermediate file
+gFvTotalSizePattern = re.compile(r"EFI_FV_TOTAL_SIZE = (0x[0-9a-fA-F]+)")
+gFvTakenSizePattern = re.compile(r"EFI_FV_TAKEN_SIZE = (0x[0-9a-fA-F]+)")
+
+## Pattern to find GUID value in flash description files
+gPcdGuidPattern = re.compile(r"PCD\((\w+)[.](\w+)\)")
+
+## Pattern to collect offset, GUID value pair in the flash report intermediate file 
+gOffsetGuidPattern = re.compile(r"(0x[0-9A-Fa-f]+) ([-A-Fa-f0-9]+)")
+
+## Tags for section start, end and separator
+gSectionStart = ">" + "=" * 118 + "<"
+gSectionEnd = "<" + "=" * 118 + ">" + "\n"
+gSectionSep = "=" * 120
+
+## Tags for subsection start, end and separator
+gSubSectionStart = ">" + "-" * 118 + "<"
+gSubSectionEnd = "<" + "-" * 118 + ">"
+gSubSectionSep = "-" * 120
+
+## The look up table to map PCD type to pair of report display type and DEC type
+gPcdTypeMap = {
+  'FixedAtBuild'     : ('FIXED',  'FixedAtBuild'),
+  'PatchableInModule': ('PATCH',  'PatchableInModule'),
+  'FeatureFlag'      : ('FLAG',   'FeatureFlag'),
+  'Dynamic'          : ('DYN',    'Dynamic'),
+  'DynamicHii'       : ('DYNHII', 'Dynamic'),
+  'DynamicVpd'       : ('DYNVPD', 'Dynamic'),
+  'DynamicEx'        : ('DEX',    'Dynamic'),
+  'DynamicExHii'     : ('DEXHII', 'Dynamic'),
+  'DynamicExVpd'     : ('DEXVPD', 'Dynamic'),
+  }
+
+##
+# Writes a string to the file object.
+# 
+# This function writes a string to the file object and a new line is appended 
+# afterwards. It may optionally wraps the string for better readability.   
+#
+# @File                      The file object to write
+# @String                    The string to be written to the file
+# @Wrapper                   Indicates whether to wrap the string
+#
+def FileWrite(File, String, Wrapper=False):
+    if Wrapper:
+        String = textwrap.fill(String, 120)
+    File.write(String + "\n")
+
+
+##
+# Reports library information
+#
+# This class reports the module library subsection in the build report file.
+#     
+class LibraryReport(object):
+    ##
+    # Constructor function for class LibraryReport
+    #
+    # This constructor function generates LibraryReport object for 
+    # a module.
+    #
+    # @param self            The object pointer
+    # @param M               Module context information
+    #
+    def __init__(self, M):
+        self.LibraryList = []
+        if int(str(M.AutoGenVersion), 0) >= 0x00010005:
+            self._EdkIIModule = True
+        else:
+            self._EdkIIModule = False
+               
+        for Lib in M.DependentLibraryList:
+            LibInfPath = str(Lib)
+            LibClassList = Lib.LibraryClass[0].LibraryClass
+            LibConstructorList = Lib.ConstructorList
+            LibDesstructorList = Lib.DestructorList
+            LibDepexList = Lib.DepexExpression[M.Arch, M.ModuleType]
+            self.LibraryList.append((LibInfPath, LibClassList, LibConstructorList, LibDesstructorList, LibDepexList))
+    
+    ##
+    # Generate report for module library information
+    #
+    # This function generates report for the module library.
+    # If the module is EDKII style one, the additional library class, library
+    # constructor/destructor and dependency expression may also be reported.  
+    #
+    # @param self            The object pointer
+    # @param File            The file object for report
+    #
+    def GenerateReport(self, File):
+        FileWrite(File, gSubSectionStart)
+        FileWrite(File, "Library")
+        if len(self.LibraryList) > 0:
+            FileWrite(File, gSubSectionSep)
+            for LibraryItem in self.LibraryList:
+                LibInfPath = LibraryItem[0]
+                FileWrite(File, LibInfPath)
+                
+                #
+                # Report library class, library constructor and destructor for
+                # EDKII style module.
+                #
+                if self._EdkIIModule:
+                    LibClass = LibraryItem[1]
+                    EdkIILibInfo = ""
+                    LibConstructor = " ".join(LibraryItem[2])
+                    if LibConstructor:
+                        EdkIILibInfo += " C = " + LibConstructor
+                    LibDestructor = " ".join(LibraryItem[3])
+                    if LibDestructor:
+                        EdkIILibInfo += " D = " + LibConstructor
+                    LibDepex = " ".join(LibraryItem[3])
+                    if LibDepex:
+                        EdkIILibInfo += " Depex = " + LibDepex
+                    if EdkIILibInfo:
+                        FileWrite(File, "{%s: %s}" % (LibClass, EdkIILibInfo))
+                    else:
+                        FileWrite(File, "{%s}" % LibClass)
+        
+        FileWrite(File, gSubSectionEnd)
+
+##
+# Reports dependency expression information
+#
+# This class reports the module dependency expression subsection in the build report file.
+#             
+class DepexReport(object):
+    ##
+    # Constructor function for class DepexReport
+    #
+    # This constructor function generates DepexReport object for 
+    # a module. If the module source contains the DXS file (usually EDK
+    # style module), it uses the dependency in DXS file; otherwise,
+    # it uses the dependency expression from its own INF [Depex] section
+    # and then merges with the ones from its dependent library INF.
+    #
+    # @param self            The object pointer
+    # @param M               Module context information
+    #
+    def __init__(self, M):
+        for Source in M.SourceFileList:
+            if os.path.splitext(Source.Path)[1].lower() == ".dxs":
+                Match = gDxsDependencyPattern.search(open(Source.Path).read())
+                if Match:
+                    self.Depex = Match.group(1).strip()
+                    self.Source = "DXS"
+                    break
+        else:
+            self.Depex = M.DepexExpressionList[M.ModuleType]
+            self.ModuleDepex = " ".join(M.Module.DepexExpression[M.Arch, M.ModuleType])
+            if not self.ModuleDepex:
+                self.ModuleDepex = "TRUE"
+            
+            LibDepexList = []
+            for Lib in M.DependentLibraryList:
+                LibDepex = " ".join(Lib.DepexExpression[M.Arch, M.ModuleType]).strip()
+                if LibDepex != "":                         
+                    if " " in LibDepex:
+                        LibDepex = "(" + LibDepex + ")"
+                    LibDepexList.append(LibDepex)
+            self.LibraryDepex = " AND ".join(LibDepexList)
+            if not self.LibraryDepex:
+                self.LibraryDepex = "(None)"
+            self.Source = "INF"
+    
+    ##
+    # Generate report for module dependency expression information
+    #
+    # This function generates report for the module dependency expression.
+    #
+    # @param self            The object pointer
+    # @param File            The file object for report
+    #
+    def GenerateReport(self, File):
+        FileWrite(File, gSubSectionStart)
+        FileWrite(File, "Dependency Expression (DEPEX) from %s" % self.Source)
+        
+        if self.Source == "INF":
+            FileWrite(File, "%s" % self.Depex, True)
+            FileWrite(File, gSubSectionSep)
+            FileWrite(File, "From Module INF:  %s" % self.ModuleDepex, True)
+            FileWrite(File, "From Library INF: %s" % self.LibraryDepex, True)
+        else:
+            FileWrite(File, "%s" % self.Depex)
+        FileWrite(File, gSubSectionEnd)
+
+##
+# Reports dependency expression information
+#
+# This class reports the module build flags subsection in the build report file.
+#                     
+class BuildFlagsReport(object):
+    ##
+    # Constructor function for class BuildFlagsReport
+    #
+    # This constructor function generates BuildFlagsReport object for 
+    # a module. It reports the build tool chain tag and all relevant 
+    # build flags to build the module.
+    #
+    # @param self            The object pointer
+    # @param M               Module context information
+    #
+    def __init__(self, M):
+        BuildOptions = {}
+        #
+        # Add build flags according to source file extension so that
+        # irrelevant ones can be filtered out. 
+        #
+        for Source in M.SourceFileList:
+            Ext = os.path.splitext(Source.File)[1].lower()
+            if Ext in [".c", ".cc", ".cpp"]:
+                BuildOptions["CC"] = 1
+            elif Ext in [".s", ".asm"]:
+                BuildOptions["PP"] = 1
+                BuildOptions["ASM"] = 1
+            elif Ext in [".vfr"]:
+                BuildOptions["VFRPP"] = 1
+                BuildOptions["VFR"] = 1
+            elif Ext in [".dxs"]:
+                BuildOptions["APP"] = 1
+                BuildOptions["CC"] = 1
+            elif Ext in [".asl"]:
+                BuildOptions["ASLPP"] = 1
+                BuildOptions["ASL"] = 1
+            elif Ext in [".aslc"]:
+                BuildOptions["ASLCC"] = 1
+                BuildOptions["ASLDLINK"] = 1
+                BuildOptions["CC"] = 1
+            elif Ext in [".asm16"]:
+                BuildOptions["ASMLINK"] = 1
+            BuildOptions["SLINK"] = 1
+            BuildOptions["DLINK"] = 1
+        
+        #
+        # Save module build flags.
+        #
+        self.ToolChainTag = M.ToolChain
+        self.BuildFlags = {}
+        for Tool in BuildOptions:
+            self.BuildFlags[Tool + "_FLAGS"] = M.BuildOption.get(Tool, {}).get("FLAGS", "")
+
+    ##
+    # Generate report for module build flags information
+    #
+    # This function generates report for the module build flags expression.
+    #
+    # @param self            The object pointer
+    # @param File            The file object for report
+    #
+    def GenerateReport(self, File):
+        FileWrite(File, gSubSectionStart)
+        FileWrite(File, "Build Flags")
+        FileWrite(File, "Tool Chain Tag: %s" % self.ToolChainTag)
+        for Tool in self.BuildFlags:
+            FileWrite(File, gSubSectionSep)
+            FileWrite(File, "%s = %s" % (Tool, self.BuildFlags[Tool]), True)
+        
+        FileWrite(File, gSubSectionEnd)
+                       
+##
+# Reports individual module information
+#
+# This class reports the module section in the build report file. 
+# It comprises of module summary, module PCD, library, dependency expression,
+# build flags sections.  
+#        
+class ModuleReport(object):
+    ##
+    # Constructor function for class ModuleReport
+    #
+    # This constructor function generates ModuleReport object for 
+    # a separate module in a platform build.  
+    #
+    # @param self            The object pointer
+    # @param M               Module context information
+    # @param DscOverridePcds Module DSC override PCD information
+    # @param ReportType      The kind of report items in the final report file
+    #
+    def __init__(self, M, DscOverridePcds, ReportType):
+        self.ModuleName = M.Module.BaseName
+        self.ModuleInfPath = M.MetaFile.File
+        self.FileGuid = M.Guid
+        self.Size = 0
+        self.BuildTimeStamp = ""
+        self.DriverType = ""
+        self.UefiSpecVersion = M.Module.Specification.get("UEFI_SPECIFICATION_VERSION", "")
+        self.PiSpecVersion = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "")
+        self.PciDeviceId = M.Module.Defines.get("PCI_DEVICE_ID", "")
+        self.PciVendorId = M.Module.Defines.get("PCI_VENDOR_ID", "")
+        self.PciClassCode = M.Module.Defines.get("PCI_CLASS_CODE", "")
+  
+        self.ModulePcdSet = {}
+        self.ModuleDscOverridePcds = {}
+        if "PCD" in ReportType:
+            #
+            # Collect all module used PCD set: module INF referenced directly or indirectly.
+            # It also saves module INF default values of them in case they exist.
+            #
+            for Pcd in M.ModulePcdList + M.LibraryPcdList:
+                self.ModulePcdSet.setdefault((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Type), Pcd.InfDefaultValue)
+            
+            #
+            # Collect module DSC override PCD set for report
+            #
+            for (PcdTokenCName, PcdTokenSpaceGuidCName) in DscOverridePcds:
+                Pcd = DscOverridePcds[(PcdTokenCName, PcdTokenSpaceGuidCName)]
+                self.ModuleDscOverridePcds.setdefault((PcdTokenCName, PcdTokenSpaceGuidCName), Pcd.DefaultValue)
+        
+        self.LibraryReport = None
+        if "LIBRARY" in ReportType:
+            self.LibraryReport = LibraryReport(M)
+        
+        self.DepexReport = None
+        if "DEPEX" in ReportType:
+            self.DepexReport = DepexReport(M)
+        
+        if "BUILD_FLAGS" in ReportType:
+            self.BuildFlagsReport = BuildFlagsReport(M)
+    
+    ##
+    # Generate report for module information
+    #
+    # This function generates report for separate module expression
+    # in a platform build.
+    #
+    # @param self            The object pointer
+    # @param File            The file object for report
+    # @param GlobalPcdReport The platform global PCD class object
+    # @param ReportType      The kind of report items in the final report file
+    #
+    def GenerateReport(self, File, GlobalPcdReport, ReportType):
+        FileWrite(File, gSectionStart)
+        
+        FileWrite(File, "Module Summary")
+        FileWrite(File, "Module Name:          %s" % self.ModuleName)
+        FileWrite(File, "Module INF Path:      %s" % self.ModuleInfPath)
+        FileWrite(File, "File GUID:            %s" % self.FileGuid)
+        if self.Size:
+            FileWrite(File, "Size:                 %s" % self.Size)
+        if self.BuildTimeStamp:
+            FileWrite(File, "Build Time Stamp:     %s" % self.BuildTimeStamp)
+        if self.DriverType:
+            FileWrite(File, "Driver Type:          %s" % self.DriverType)
+        if self.UefiSpecVersion:
+            FileWrite(File, "UEFI Spec Version:    %s" % self.DriverType)
+        if self.PiSpecVersion:
+            FileWrite(File, "PI Spec Version:      %s" % self.PiSpecVersion)
+        if self.PciDeviceId:
+            FileWrite(File, "PCI Device ID:        %s" % self.PciDeviceId)
+        if self.PciVendorId:
+            FileWrite(File, "PCI Vendor ID:        %s" % self.PciVendorId)
+        if self.PciClassCode:
+            FileWrite(File, "PCI Class Code:       %s" % self.PciClassCode)
+        
+        FileWrite(File, gSectionSep)   
+        
+        if "PCD" in ReportType:
+            GlobalPcdReport.GenerateReport(File, self.ModulePcdSet, self.ModuleDscOverridePcds)
+        
+        if "LIBRARY" in ReportType:
+            self.LibraryReport.GenerateReport(File)
+        
+        if "DEPEX" in ReportType:
+            self.DepexReport.GenerateReport(File)
+        
+        if "BUILD_FLAGS" in ReportType:
+            self.BuildFlagsReport.GenerateReport(File)
+        
+        FileWrite(File, gSectionEnd)
+
+##
+# Reports platform and module PCD information
+#
+# This class reports the platform PCD section and module PCD subsection
+# in the build report file.
+#     
+class PcdReport(object):
+    ##
+    # Constructor function for class PcdReport
+    #
+    # This constructor function generates PcdReport object a platform build.
+    # It collects the whole PCD database from platform DSC files, platform
+    # flash description file and package DEC files.
+    #
+    # @param self            The object pointer
+    # @param Wa              Workspace context information
+    #
+    def __init__(self, Wa):
+        self.AllPcds = {}
+        self.MaxLen = 0
+        self.FdfPcdSet = Wa.FdfProfile.PcdDict
+
+        self.DecPcdDefault = {}
+        self.ModulePcdOverride = {}
+        for Pa in Wa.AutoGenObjectList:
+            #
+            # Collect all platform referenced PCDs and grouped them by PCD token space
+            # GUID C Names
+            #
+            for Pcd in Pa.AllPcdList:
+                PcdList = self.AllPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, [])
+                if Pcd not in PcdList:
+                    PcdList.append(Pcd)
+                if len(Pcd.TokenCName) > self.MaxLen:
+                    self.MaxLen = len(Pcd.TokenCName)
+            
+            for ModuleKey in Pa.Platform.Modules:
+                #
+                # Collect PCD DEC default value.
+                #   
+                Module = Pa.Platform.Modules[ModuleKey]
+                for Package in Module.M.Module.Packages:
+                    for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:
+                        DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue
+                        self.DecPcdDefault.setdefault((TokenCName, TokenSpaceGuidCName, DecType), DecDefaultValue)
+                #
+                # Collect module override PCDs
+                #
+                for ModulePcd in Module.M.ModulePcdList + Module.M.LibraryPcdList:
+                    TokenCName = ModulePcd.TokenCName
+                    TokenSpaceGuid = ModulePcd.TokenSpaceGuidCName
+                    ModuleDefault = ModulePcd.DefaultValue
+                    ModulePath = os.path.basename(Module.M.MetaFile.File)
+                    self.ModulePcdOverride.setdefault((TokenCName, TokenSpaceGuid), []).append((ModuleDefault, ModulePath))
+
+        #
+        # Collect PCDs defined in DSC common section
+        #
+        self.DscPcdDefault = {}
+        for Platform in Wa.BuildDatabase.WorkspaceDb.PlatformList:
+            for (TokenCName, TokenSpaceGuidCName) in Platform.Pcds:
+                DscDefaultValue = Platform.Pcds[(TokenCName, TokenSpaceGuidCName)].DefaultValue
+                self.DscPcdDefault[(TokenCName, TokenSpaceGuidCName)] = DscDefaultValue
+    
+    ##
+    # Generate report for PCD information
+    #
+    # This function generates report for separate module expression
+    # in a platform build.
+    #
+    # @param self            The object pointer
+    # @param File            The file object for report
+    # @param ModulePcdSet    Set of all PCDs referenced by module or None for
+    #                        platform PCD report
+    # @param DscOverridePcds Module DSC override PCDs set
+    #
+    def GenerateReport(self, File, ModulePcdSet, DscOverridePcds):
+        if ModulePcdSet == None:
+            #
+            # For platform global PCD section
+            #
+            FileWrite(File, gSectionStart)
+            FileWrite(File, "Platform Configuration Database Report")
+            FileWrite(File, "  *P  - Platform scoped PCD override in DSC file")
+            FileWrite(File, "  *F  - Platform scoped PCD override in FDF file")
+            FileWrite(File, "  *M  - Module scoped PCD override in DSC file")
+            FileWrite(File, gSectionSep)
+        else:
+            #
+            # For module PCD sub-section
+            #
+            FileWrite(File, gSubSectionStart)
+            FileWrite(File, "PCD")
+            FileWrite(File, gSubSectionSep)
+
+        for Key in self.AllPcds:
+            #
+            # Group PCD by their token space GUID C Name
+            #
+            First = True
+            for Type in self.AllPcds[Key]:
+                #
+                # Group PCD by their usage type
+                #
+                TypeName, DecType = gPcdTypeMap.get(Type, ("", Type))
+                for Pcd in self.AllPcds[Key][Type]:
+                    #
+                    # Get PCD default value and their override relationship
+                    #
+                    InfDefaultValue = None
+                    if ModulePcdSet != None:
+                        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type) not in ModulePcdSet:
+                            continue
+                        InfDefault = ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
+                        if InfDefault == "":
+                            InfDefault = None
+                    if First:
+                        if ModulePcdSet == None:
+                            FileWrite(File, "")
+                        FileWrite(File, Key)
+                        First = False
+                    DecDefaultValue = self.DecPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType))
+                    DscDefaultValue = self.DscPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))
+                    DscModuleOverrideValue = DscOverridePcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))
+                          
+                    if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
+                        PcdDefaultValueNumber = int(Pcd.DefaultValue.strip(), 0)
+                        if DecDefaultValue == None:
+                            DecMatch = True
+                        else:
+                            DecDefaultValueNumber = int(DecDefaultValue.strip(), 0)
+                            DecMatch = (DecDefaultValueNumber == PcdDefaultValueNumber)
+                  
+                        if InfDefaultValue == None:
+                            InfMatch = True
+                        else:
+                            InfDefaultValueNumber = int(InfDefaultValue.strip(), 0)
+                            InfMatch = (InfDefaultValueNumber == PcdDefaultValueNumber)
+                                
+                        if DscDefaultValue == None:
+                            DscMatch = True
+                        else:
+                            DscDefaultValueNumber = int(DscDefaultValue.strip(), 0)
+                            DscMatch = (DscDefaultValueNumber == PcdDefaultValueNumber)
+                    else:
+                        if DecDefaultValue == None:
+                            DecMatch = True
+                        else:
+                            DecMatch = (DecDefaultValue == Pcd.DefaultValue)
+                  
+                        if InfDefaultValue == None:
+                            InfMatch = True
+                        else:
+                            InfMatch = (InfDefaultValue == Pcd.DefaultValue)
+                            
+                        if DscDefaultValue == None:
+                            DscMatch = True
+                        else:
+                            DscMatch = (DscDefaultValue == Pcd.DefaultValue)
+                    
+                    #
+                    # Report PCD item according to their override relationship
+                    #        
+                    if DecMatch and InfMatch:
+                        FileWrite(File, '    %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', Pcd.DefaultValue))
+                    else:
+                        if DscMatch and DscModuleOverrideValue == None:
+                            if (Pcd.TokenCName, Key) in self.FdfPcdSet:
+                                FileWrite(File, ' *F %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', Pcd.DefaultValue))
+                            else:
+                                FileWrite(File, ' *P %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', Pcd.DefaultValue))
+                        else:
+                            FileWrite(File, ' *M %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', Pcd.DefaultValue))
+                            if DscDefaultValue != None:
+                                FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', DscDefaultValue))
+                        
+                        if InfDefaultValue != None:
+                            FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', InfDefaultValue))
+                        
+                        if DecDefaultValue != None and not DecMatch:
+                            FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', DecDefaultValue))
+
+                    if ModulePcdSet == None:
+                        for (ModuleDefault, ModulePath) in self.ModulePcdOverride.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), []):
+                            if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
+                                ModulePcdDefaultValueNumber = int(ModuleDefault.strip(), 0)
+                                Match = (ModulePcdDefaultValueNumber == PcdDefaultValueNumber)
+                            else:
+                                Match = (ModuleDefault == Pcd.DefaultValue)
+                            if Match:
+                                continue
+                            FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 19, ModulePath, ModuleDefault))
+        
+        if ModulePcdSet == None:
+            FileWrite(File, gSectionEnd)
+        else:
+            FileWrite(File, gSubSectionEnd)     
+
+
+##
+# Reports platform information
+#
+# This class reports the whole platform information 
+#     
+class PlatformReport(object):
+    ##
+    # Constructor function for class PlatformReport
+    #
+    # This constructor function generates PlatformReport object a platform build.
+    # It generates report for platform summary, flash, global PCDs and detailed
+    # module information for modules involved in platform build.
+    #
+    # @param self            The object pointer
+    # @param Wa              Workspace context information
+    #
+    def __init__(self, Wa, ReportType):
+        self._WorkspaceDir = Wa.WorkspaceDir
+        self.PlatformName = Wa.Name
+        self.PlatformDscPath = Wa.Platform
+        self.Architectures = " ".join(Wa.ArchList)
+        self.ToolChain = Wa.ToolChain
+        self.Target = Wa.BuildTarget
+        self.OutputPath = os.path.join(Wa.WorkspaceDir, Wa.OutputDir)
+        self.BuildEnvironment = platform.platform()
+        
+        self.PcdReport = None
+        if "PCD" in ReportType:
+            self.PcdReport = PcdReport(Wa)
+
+        self.ModuleReportList = []
+        for Pa in Wa.AutoGenObjectList:
+            for ModuleKey in Pa.Platform.Modules:
+                for Platform in Wa.BuildDatabase.WorkspaceDb.PlatformList:
+                    if ModuleKey in Platform.Modules:
+                        DscOverridePcds = Platform.Modules[ModuleKey].Pcds
+                        break
+                else:
+                    DscOverridePcds = {}
+                self.ModuleReportList.append(ModuleReport(Pa.Platform.Modules[ModuleKey].M, DscOverridePcds, ReportType))
+    ##
+    # Generate report for the whole platform.
+    #
+    # This function generates report for platform information.
+    # It comprises of platform summary, global PCD, flash and 
+    # module list sections.
+    #
+    # @param self            The object pointer
+    # @param File            The file object for report
+    # @param BuildDuration   The total time to build the modules
+    # @param ReportType      The kind of report items in the final report file
+    #
+    def GenerateReport(self, File, BuildDuration, ReportType):
+        FileWrite(File, "Platform Summary")
+        FileWrite(File, "Platform Name:        %s" % self.PlatformName)
+        FileWrite(File, "Platform DSC Path:    %s" % self.PlatformDscPath)
+        FileWrite(File, "Platform DSC Path:    %s" % self.Architectures)
+        FileWrite(File, "Tool Chain:           %s" % self.ToolChain)
+        FileWrite(File, "Target:               %s" % self.Target)
+        FileWrite(File, "Output Path:          %s" % self.OutputPath)
+        FileWrite(File, "Build Environment:    %s" % self.BuildEnvironment)
+        FileWrite(File, "Build Duration:       %s" % BuildDuration)
+        FileWrite(File, "Report Content:       %s" % ", ".join(ReportType))
+        if "PCD" in ReportType:
+            self.PcdReport.GenerateReport(File, None, {})
+            
+       
+        for ModuleReportItem in self.ModuleReportList:
+            ModuleReportItem.GenerateReport(File, self.PcdReport, ReportType)
+        
+
+## BuildReport class
+#
+#  This base class contain the routines to collect data and then
+#  applies certain format to the output report 
+#
+class BuildReport(object):
+    ##
+    # Constructor function for class BuildReport
+    #
+    # This constructor function generates BuildReport object a platform build.
+    # It generates report for platform summary, flash, global PCDs and detailed
+    # module information for modules involved in platform build.
+    #
+    # @param self            The object pointer
+    # @param ReportFile      The file name to save report file
+    # @param ReportType      The kind of report items in the final report file
+    #
+    def __init__(self, ReportFile, ReportType):
+        self.ReportFile = ReportFile
+        if ReportFile:
+            self.ReportList = []
+            if ReportType == None or "ALL" in ReportType:
+                self.ReportType = ["PCD", "LIBRARY", "BUILD_FLAGS", "DEPEX", "FLASH", "PREDICTION"]
+            else:
+                for ReportTypeItem in ReportType:
+                    if ReportTypeItem not in self.ReportType:
+                        self.ReportType.append(ReportTypeItem)
+    
+    ##
+    # Adds platform report to the list
+    #
+    # This function adds a platform report to the final report list.
+    #
+    # @param self            The object pointer
+    # @param Wa              Workspace context information
+    #           
+    def AddPlatformReport(self, Wa):
+        if self.ReportFile:
+            self.ReportList.append(PlatformReport(Wa, self.ReportType))
+
+    ##
+    # Generates the final report.
+    #
+    # This function generates platform build report. It invokes GenerateReport()
+    # method for every platform report in the list.
+    #
+    # @param self            The object pointer
+    # @param BuildDuration   The total time to build the modules
+    # 
+    def GenerateReport(self, BuildDuration):
+        if self.ReportFile:
+            try:
+                File = open(self.ReportFile, "w+")
+            except IOError:
+                EdkLogger.error(None, FILE_OPEN_FAILURE, ExtraData=self.ReportFile)
+            try:
+                for Report in self.ReportList:
+                    Report.GenerateReport(File, BuildDuration, self.ReportType) 
+            except IOError:
+                EdkLogger.error(None, FILE_WRITE_FAILURE, ExtraData=self.ReportFile)
+            File.close()
+        
+# This acts like the main() function for the script, unless it is 'import'ed into another script.
+if __name__ == '__main__':
+    pass
+
index 624d941..539fd77 100644 (file)
-## @file
-# build a platform or a module
-#
-#  Copyright (c) 2007, Intel Corporation
-#
-#  All rights reserved. This program and the accompanying materials
-#  are licensed and made available under the terms and conditions of the BSD License
-#  which accompanies this distribution.  The full text of the license may be found at
-#  http://opensource.org/licenses/bsd-license.php
-#
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-
-##
-# Import Modules
-#
-import os
-import re
-import sys
-import glob
-import time
-import platform
-import traceback
-
-from threading import *
-from optparse import OptionParser
-from subprocess import *
-from Common import Misc as Utils
-
-from Common.TargetTxtClassObject import *
-from Common.ToolDefClassObject import *
-from Common.DataType import *
-from AutoGen.AutoGen import *
-from Common.BuildToolError import *
-from Workspace.WorkspaceDatabase import *
-
-import Common.EdkLogger
-import Common.GlobalData as GlobalData
-
-# Version and Copyright
-VersionNumber = "0.5"
-__version__ = "%prog Version " + VersionNumber
-__copyright__ = "Copyright (c) 2007, Intel Corporation  All rights reserved."
-
-## standard targets of build command
-gSupportedTarget = ['all', 'genc', 'genmake', 'modules', 'libraries', 'fds', 'clean', 'cleanall', 'cleanlib', 'run']
-
-## build configuration file
-gBuildConfiguration = "Conf/target.txt"
-gBuildCacheDir = "Conf/.cache"
-gToolsDefinition = "Conf/tools_def.txt"
-
-## Check environment PATH variable to make sure the specified tool is found
-#
-#   If the tool is found in the PATH, then True is returned
-#   Otherwise, False is returned
-#
-def IsToolInPath(tool):
-    if os.environ.has_key('PATHEXT'):
-        extns = os.environ['PATHEXT'].split(os.path.pathsep)
-    else:
-        extns = ('',)
-    for pathDir in os.environ['PATH'].split(os.path.pathsep):
-        for ext in extns:
-            if os.path.exists(os.path.join(pathDir, tool + ext)):
-                return True
-    return False
-
-## Check environment variables
-#
-#  Check environment variables that must be set for build. Currently they are
-#
-#   WORKSPACE           The directory all packages/platforms start from
-#   EDK_TOOLS_PATH      The directory contains all tools needed by the build
-#   PATH                $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH
-#
-#   If any of above environment variable is not set or has error, the build
-#   will be broken.
-#
-def CheckEnvVariable():
-    # check WORKSPACE
-    if "WORKSPACE" not in os.environ:
-        EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
-                        ExtraData="WORKSPACE")
-
-    WorkspaceDir = os.path.normcase(os.path.normpath(os.environ["WORKSPACE"]))
-    if not os.path.exists(WorkspaceDir):
-        EdkLogger.error("build", FILE_NOT_FOUND, "WORKSPACE doesn't exist", ExtraData="%s" % WorkspaceDir)
-    elif ' ' in WorkspaceDir:
-        EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in WORKSPACE path",
-                        ExtraData=WorkspaceDir)
-    os.environ["WORKSPACE"] = WorkspaceDir
-
-    #
-    # Check EFI_SOURCE (R8 build convention). EDK_SOURCE will always point to ECP
-    #
-    os.environ["ECP_SOURCE"] = os.path.join(WorkspaceDir, GlobalData.gEdkCompatibilityPkg)
-    if "EFI_SOURCE" not in os.environ:
-        os.environ["EFI_SOURCE"] = os.environ["ECP_SOURCE"]
-    if "EDK_SOURCE" not in os.environ:
-        os.environ["EDK_SOURCE"] = os.environ["ECP_SOURCE"]
-
-    #
-    # Unify case of characters on case-insensitive systems
-    #
-    EfiSourceDir = os.path.normcase(os.path.normpath(os.environ["EFI_SOURCE"]))
-    EdkSourceDir = os.path.normcase(os.path.normpath(os.environ["EDK_SOURCE"]))
-    EcpSourceDir = os.path.normcase(os.path.normpath(os.environ["ECP_SOURCE"]))
-    os.environ["EFI_SOURCE"] = EfiSourceDir
-    os.environ["EDK_SOURCE"] = EdkSourceDir
-    os.environ["ECP_SOURCE"] = EcpSourceDir
-    os.environ["EDK_TOOLS_PATH"] = os.path.normcase(os.environ["EDK_TOOLS_PATH"])
-    
-    if not os.path.exists(EcpSourceDir):
-        EdkLogger.verbose("ECP_SOURCE = %s doesn't exist. R8 modules could not be built." % EcpSourceDir)
-    elif ' ' in EcpSourceDir:
-        EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in ECP_SOURCE path",
-                        ExtraData=EcpSourceDir)
-    if not os.path.exists(EdkSourceDir):
-        if EdkSourceDir == EcpSourceDir:
-            EdkLogger.verbose("EDK_SOURCE = %s doesn't exist. R8 modules could not be built." % EdkSourceDir)
-        else:
-            EdkLogger.error("build", PARAMETER_INVALID, "EDK_SOURCE does not exist",
-                            ExtraData=EdkSourceDir)
-    elif ' ' in EdkSourceDir:
-        EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in EDK_SOURCE path",
-                        ExtraData=EdkSourceDir)
-    if not os.path.exists(EfiSourceDir):
-        if EfiSourceDir == EcpSourceDir:
-            EdkLogger.verbose("EFI_SOURCE = %s doesn't exist. R8 modules could not be built." % EfiSourceDir)
-        else:
-            EdkLogger.error("build", PARAMETER_INVALID, "EFI_SOURCE does not exist",
-                            ExtraData=EfiSourceDir)
-    elif ' ' in EfiSourceDir:
-        EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in EFI_SOURCE path",
-                        ExtraData=EfiSourceDir)
-
-    # change absolute path to relative path to WORKSPACE
-    if EfiSourceDir.upper().find(WorkspaceDir.upper()) != 0:
-        EdkLogger.error("build", PARAMETER_INVALID, "EFI_SOURCE is not under WORKSPACE",
-                        ExtraData="WORKSPACE = %s\n    EFI_SOURCE = %s" % (WorkspaceDir, EfiSourceDir))
-    if EdkSourceDir.upper().find(WorkspaceDir.upper()) != 0:
-        EdkLogger.error("build", PARAMETER_INVALID, "EDK_SOURCE is not under WORKSPACE",
-                        ExtraData="WORKSPACE = %s\n    EDK_SOURCE = %s" % (WorkspaceDir, EdkSourceDir))
-    if EcpSourceDir.upper().find(WorkspaceDir.upper()) != 0:
-        EdkLogger.error("build", PARAMETER_INVALID, "ECP_SOURCE is not under WORKSPACE",
-                        ExtraData="WORKSPACE = %s\n    ECP_SOURCE = %s" % (WorkspaceDir, EcpSourceDir))
-
-    # check EDK_TOOLS_PATH
-    if "EDK_TOOLS_PATH" not in os.environ:
-        EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
-                        ExtraData="EDK_TOOLS_PATH")
-
-    # check PATH
-    if "PATH" not in os.environ:
-        EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
-                        ExtraData="PATH")
-
-    GlobalData.gWorkspace = WorkspaceDir
-    GlobalData.gEfiSource = EfiSourceDir
-    GlobalData.gEdkSource = EdkSourceDir
-    GlobalData.gEcpSource = EcpSourceDir
-
-## Get normalized file path
-#
-# Convert the path to be local format, and remove the WORKSPACE path at the
-# beginning if the file path is given in full path.
-#
-# @param  FilePath      File path to be normalized
-# @param  Workspace     Workspace path which the FilePath will be checked against
-#
-# @retval string        The normalized file path
-#
-def NormFile(FilePath, Workspace):
-    # check if the path is absolute or relative
-    if os.path.isabs(FilePath):
-        FileFullPath = os.path.normpath(FilePath)
-    else:
-        FileFullPath = os.path.normpath(os.path.join(Workspace, FilePath))
-
-    # check if the file path exists or not
-    if not os.path.isfile(FileFullPath):
-        EdkLogger.error("build", FILE_NOT_FOUND, ExtraData="\t%s (Please give file in absolute path or relative to WORKSPACE)"  % FileFullPath)
-
-    # remove workspace directory from the beginning part of the file path
-    if Workspace[-1] in ["\\", "/"]:
-        return FileFullPath[len(Workspace):]
-    else:
-        return FileFullPath[(len(Workspace) + 1):]
-
-## Get the output of an external program
-#
-# This is the entrance method of thread reading output of an external program and
-# putting them in STDOUT/STDERR of current program.
-#
-# @param  From      The stream message read from
-# @param  To        The stream message put on
-# @param  ExitFlag  The flag used to indicate stopping reading
-#
-def ReadMessage(From, To, ExitFlag):
-    while True:
-        # read one line a time
-        Line = From.readline()
-        # empty string means "end"
-        if Line != None and Line != "":
-            To(Line.rstrip())
-        else:
-            break
-        if ExitFlag.isSet():
-            break
-
-## Launch an external program
-#
-# This method will call subprocess.Popen to execute an external program with
-# given options in specified directory. Because of the dead-lock issue during
-# redirecting output of the external program, threads are used to to do the
-# redirection work.
-#
-# @param  Command               A list or string containing the call of the program
-# @param  WorkingDir            The directory in which the program will be running
-#
-def LaunchCommand(Command, WorkingDir):
-    # if working directory doesn't exist, Popen() will raise an exception
-    if not os.path.isdir(WorkingDir):
-        EdkLogger.error("build", FILE_NOT_FOUND, ExtraData=WorkingDir)
-
-    Proc = None
-    EndOfProcedure = None
-    try:
-        # launch the command
-        Proc = Popen(Command, stdout=PIPE, stderr=PIPE, env=os.environ, cwd=WorkingDir, bufsize=-1)
-
-        # launch two threads to read the STDOUT and STDERR
-        EndOfProcedure = Event()
-        EndOfProcedure.clear()
-        if Proc.stdout:
-            StdOutThread = Thread(target=ReadMessage, args=(Proc.stdout, EdkLogger.info, EndOfProcedure))
-            StdOutThread.setName("STDOUT-Redirector")
-            StdOutThread.setDaemon(False)
-            StdOutThread.start()
-
-        if Proc.stderr:
-            StdErrThread = Thread(target=ReadMessage, args=(Proc.stderr, EdkLogger.quiet, EndOfProcedure))
-            StdErrThread.setName("STDERR-Redirector")
-            StdErrThread.setDaemon(False)
-            StdErrThread.start()
-
-        # waiting for program exit
-        Proc.wait()
-    except: # in case of aborting
-        # terminate the threads redirecting the program output
-        if EndOfProcedure != None:
-            EndOfProcedure.set()
-        if Proc == None:
-            if type(Command) != type(""):
-                Command = " ".join(Command)
-            EdkLogger.error("build", COMMAND_FAILURE, "Failed to start command", ExtraData="%s [%s]" % (Command, WorkingDir))
-
-    if Proc.stdout:
-        StdOutThread.join()
-    if Proc.stderr:
-        StdErrThread.join()
-
-    # check the return code of the program
-    if Proc.returncode != 0:
-        if type(Command) != type(""):
-            Command = " ".join(Command)
-        EdkLogger.error("build", COMMAND_FAILURE, ExtraData="%s [%s]" % (Command, WorkingDir))
-
-## The smallest unit that can be built in multi-thread build mode
-#
-# This is the base class of build unit. The "Obj" parameter must provide
-# __str__(), __eq__() and __hash__() methods. Otherwise there could be build units
-# missing build.
-#
-# Currently the "Obj" should be only ModuleAutoGen or PlatformAutoGen objects.
-#
-class BuildUnit:
-    ## The constructor
-    #
-    #   @param  self        The object pointer
-    #   @param  Obj         The object the build is working on
-    #   @param  Target      The build target name, one of gSupportedTarget
-    #   @param  Dependency  The BuildUnit(s) which must be completed in advance
-    #   @param  WorkingDir  The directory build command starts in
-    #
-    def __init__(self, Obj, BuildCommand, Target, Dependency, WorkingDir="."):
-        self.BuildObject = Obj
-        self.Dependency = Dependency
-        self.WorkingDir = WorkingDir
-        self.Target = Target
-        self.BuildCommand = BuildCommand
-        if BuildCommand == None or len(BuildCommand) == 0:
-            EdkLogger.error("build", OPTION_MISSING, "No build command found for",
-                            ExtraData=str(Obj))
-
-    ## str() method
-    #
-    #   It just returns the string representaion of self.BuildObject
-    #
-    #   @param  self        The object pointer
-    #
-    def __str__(self):
-        return str(self.BuildObject)
-
-    ## "==" operator method
-    #
-    #   It just compares self.BuildObject with "Other". So self.BuildObject must
-    #   provide its own __eq__() method.
-    #
-    #   @param  self        The object pointer
-    #   @param  Other       The other BuildUnit object compared to
-    #
-    def __eq__(self, Other):
-        return Other != None and self.BuildObject == Other.BuildObject \
-                and self.BuildObject.Arch == Other.BuildObject.Arch
-
-    ## hash() method
-    #
-    #   It just returns the hash value of self.BuildObject which must be hashable.
-    #
-    #   @param  self        The object pointer
-    #
-    def __hash__(self):
-        return hash(self.BuildObject) + hash(self.BuildObject.Arch)
-
-    def __repr__(self):
-        return repr(self.BuildObject)
-
-## The smallest module unit that can be built by nmake/make command in multi-thread build mode
-#
-# This class is for module build by nmake/make build system. The "Obj" parameter
-# must provide __str__(), __eq__() and __hash__() methods. Otherwise there could
-# be make units missing build.
-#
-# Currently the "Obj" should be only ModuleAutoGen object.
-#
-class ModuleMakeUnit(BuildUnit):
-    ## The constructor
-    #
-    #   @param  self        The object pointer
-    #   @param  Obj         The ModuleAutoGen object the build is working on
-    #   @param  Target      The build target name, one of gSupportedTarget
-    #
-    def __init__(self, Obj, Target):
-        Dependency = [ModuleMakeUnit(La, Target) for La in Obj.LibraryAutoGenList]
-        BuildUnit.__init__(self, Obj, Obj.BuildCommand, Target, Dependency, Obj.MakeFileDir)
-        if Target in [None, "", "all"]:
-            self.Target = "tbuild"
-
-## The smallest platform unit that can be built by nmake/make command in multi-thread build mode
-#
-# This class is for platform build by nmake/make build system. The "Obj" parameter
-# must provide __str__(), __eq__() and __hash__() methods. Otherwise there could
-# be make units missing build.
-#
-# Currently the "Obj" should be only PlatformAutoGen object.
-#
-class PlatformMakeUnit(BuildUnit):
-    ## The constructor
-    #
-    #   @param  self        The object pointer
-    #   @param  Obj         The PlatformAutoGen object the build is working on
-    #   @param  Target      The build target name, one of gSupportedTarget
-    #
-    def __init__(self, Obj, Target):
-        Dependency = [ModuleMakeUnit(Lib, Target) for Lib in self.BuildObject.LibraryAutoGenList]
-        Dependency.extend([ModuleMakeUnit(Mod, Target) for Mod in self.BuildObject.ModuleAutoGenList])
-        BuildUnit.__init__(self, Obj, Obj.BuildCommand, Target, Dependency, Obj.MakeFileDir)
-
-## The class representing the task of a module build or platform build
-#
-# This class manages the build tasks in multi-thread build mode. Its jobs include
-# scheduling thread running, catching thread error, monitor the thread status, etc.
-#
-class BuildTask:
-    # queue for tasks waiting for schedule
-    _PendingQueue = sdict()
-    _PendingQueueLock = threading.Lock()
-
-    # queue for tasks ready for running
-    _ReadyQueue = sdict()
-    _ReadyQueueLock = threading.Lock()
-
-    # queue for run tasks
-    _RunningQueue = sdict()
-    _RunningQueueLock = threading.Lock()
-
-    # queue containing all build tasks, in case duplicate build
-    _TaskQueue = sdict()
-
-    # flag indicating error occurs in a running thread
-    _ErrorFlag = threading.Event()
-    _ErrorFlag.clear()
-    _ErrorMessage = ""
-
-    # BoundedSemaphore object used to control the number of running threads
-    _Thread = None
-
-    # flag indicating if the scheduler is started or not
-    _SchedulerStopped = threading.Event()
-    _SchedulerStopped.set()
-
-    ## Start the task scheduler thread
-    #
-    #   @param  MaxThreadNumber     The maximum thread number
-    #   @param  ExitFlag            Flag used to end the scheduler
-    #
-    @staticmethod
-    def StartScheduler(MaxThreadNumber, ExitFlag):
-        SchedulerThread = Thread(target=BuildTask.Scheduler, args=(MaxThreadNumber, ExitFlag))
-        SchedulerThread.setName("Build-Task-Scheduler")
-        SchedulerThread.setDaemon(False)
-        SchedulerThread.start()
-        # wait for the scheduler to be started, especially useful in Linux
-        while not BuildTask.IsOnGoing():
-            time.sleep(0.01)
-
-    ## Scheduler method
-    #
-    #   @param  MaxThreadNumber     The maximum thread number
-    #   @param  ExitFlag            Flag used to end the scheduler
-    #
-    @staticmethod
-    def Scheduler(MaxThreadNumber, ExitFlag):
-        BuildTask._SchedulerStopped.clear()
-        try:
-            # use BoundedSemaphore to control the maximum running threads
-            BuildTask._Thread = BoundedSemaphore(MaxThreadNumber)
-            #
-            # scheduling loop, which will exits when no pending/ready task and
-            # indicated to do so, or there's error in running thread
-            #
-            while (len(BuildTask._PendingQueue) > 0 or len(BuildTask._ReadyQueue) > 0 \
-                   or not ExitFlag.isSet()) and not BuildTask._ErrorFlag.isSet():
-                EdkLogger.debug(EdkLogger.DEBUG_8, "Pending Queue (%d), Ready Queue (%d)"
-                                % (len(BuildTask._PendingQueue), len(BuildTask._ReadyQueue)))
-
-                # get all pending tasks
-                BuildTask._PendingQueueLock.acquire()
-                BuildObjectList = BuildTask._PendingQueue.keys()
-                #
-                # check if their dependency is resolved, and if true, move them
-                # into ready queue
-                #
-                for BuildObject in BuildObjectList:
-                    Bt = BuildTask._PendingQueue[BuildObject]
-                    if Bt.IsReady():
-                        BuildTask._ReadyQueue[BuildObject] = BuildTask._PendingQueue.pop(BuildObject)
-                BuildTask._PendingQueueLock.release()
-
-                # launch build thread until the maximum number of threads is reached
-                while not BuildTask._ErrorFlag.isSet():
-                    # empty ready queue, do nothing further
-                    if len(BuildTask._ReadyQueue) == 0:
-                        break
-
-                    # wait for active thread(s) exit
-                    BuildTask._Thread.acquire(True)
-
-                    # start a new build thread
-                    Bo = BuildTask._ReadyQueue.keys()[0]
-                    Bt = BuildTask._ReadyQueue.pop(Bo)
-
-                    # move into running queue
-                    BuildTask._RunningQueueLock.acquire()
-                    BuildTask._RunningQueue[Bo] = Bt
-                    BuildTask._RunningQueueLock.release()
-
-                    Bt.Start()
-                    # avoid tense loop
-                    time.sleep(0.01)
-
-                # avoid tense loop
-                time.sleep(0.01)
-
-            # wait for all running threads exit
-            if BuildTask._ErrorFlag.isSet():
-                EdkLogger.quiet("\nWaiting for all build threads exit...")
-            # while not BuildTask._ErrorFlag.isSet() and \
-            while len(BuildTask._RunningQueue) > 0:
-                EdkLogger.verbose("Waiting for thread ending...(%d)" % len(BuildTask._RunningQueue))
-                EdkLogger.debug(EdkLogger.DEBUG_8, "Threads [%s]" % ", ".join([Th.getName() for Th in threading.enumerate()]))
-                # avoid tense loop
-                time.sleep(0.1)
-        except BaseException, X:
-            #
-            # TRICK: hide the output of threads left runing, so that the user can
-            #        catch the error message easily
-            #
-            EdkLogger.SetLevel(EdkLogger.ERROR)
-            BuildTask._ErrorFlag.set()
-            BuildTask._ErrorMessage = "build thread scheduler error\n\t%s" % str(X)
-
-        BuildTask._PendingQueue.clear()
-        BuildTask._ReadyQueue.clear()
-        BuildTask._RunningQueue.clear()
-        BuildTask._TaskQueue.clear()
-        BuildTask._SchedulerStopped.set()
-
-    ## Wait for all running method exit
-    #
-    @staticmethod
-    def WaitForComplete():
-        BuildTask._SchedulerStopped.wait()
-
-    ## Check if the scheduler is running or not
-    #
-    @staticmethod
-    def IsOnGoing():
-        return not BuildTask._SchedulerStopped.isSet()
-
-    ## Abort the build
-    @staticmethod
-    def Abort():
-        if BuildTask.IsOnGoing():
-            BuildTask._ErrorFlag.set()
-            BuildTask.WaitForComplete()
-
-    ## Check if there's error in running thread
-    #
-    #   Since the main thread cannot catch exceptions in other thread, we have to
-    #   use threading.Event to communicate this formation to main thread.
-    #
-    @staticmethod
-    def HasError():
-        return BuildTask._ErrorFlag.isSet()
-
-    ## Get error message in running thread
-    #
-    #   Since the main thread cannot catch exceptions in other thread, we have to
-    #   use a static variable to communicate this message to main thread.
-    #
-    @staticmethod
-    def GetErrorMessage():
-        return BuildTask._ErrorMessage
-
-    ## Factory method to create a BuildTask object
-    #
-    #   This method will check if a module is building or has been built. And if
-    #   true, just return the associated BuildTask object in the _TaskQueue. If
-    #   not, create and return a new BuildTask object. The new BuildTask object
-    #   will be appended to the _PendingQueue for scheduling later.
-    #
-    #   @param  BuildItem       A BuildUnit object representing a build object
-    #   @param  Dependency      The dependent build object of BuildItem
-    #
-    @staticmethod
-    def New(BuildItem, Dependency=None):
-        if BuildItem in BuildTask._TaskQueue:
-            Bt = BuildTask._TaskQueue[BuildItem]
-            return Bt
-
-        Bt = BuildTask()
-        Bt._Init(BuildItem, Dependency)
-        BuildTask._TaskQueue[BuildItem] = Bt
-
-        BuildTask._PendingQueueLock.acquire()
-        BuildTask._PendingQueue[BuildItem] = Bt
-        BuildTask._PendingQueueLock.release()
-
-        return Bt
-
-    ## The real constructor of BuildTask
-    #
-    #   @param  BuildItem       A BuildUnit object representing a build object
-    #   @param  Dependency      The dependent build object of BuildItem
-    #
-    def _Init(self, BuildItem, Dependency=None):
-        self.BuildItem = BuildItem
-
-        self.DependencyList = []
-        if Dependency == None:
-            Dependency = BuildItem.Dependency
-        else:
-            Dependency.extend(BuildItem.Dependency)
-        self.AddDependency(Dependency)
-        # flag indicating build completes, used to avoid unnecessary re-build
-        self.CompleteFlag = False
-
-    ## Check if all dependent build tasks are completed or not
-    #
-    def IsReady(self):
-        ReadyFlag = True
-        for Dep in self.DependencyList:
-            if Dep.CompleteFlag == True:
-                continue
-            ReadyFlag = False
-            break
-
-        return ReadyFlag
-
-    ## Add dependent build task
-    #
-    #   @param  Dependency      The list of dependent build objects
-    #
-    def AddDependency(self, Dependency):
-        for Dep in Dependency:
-            self.DependencyList.append(BuildTask.New(Dep))    # BuildTask list
-
-    ## The thread wrapper of LaunchCommand function
-    #
-    # @param  Command               A list or string contains the call of the command
-    # @param  WorkingDir            The directory in which the program will be running
-    #
-    def _CommandThread(self, Command, WorkingDir):
-        try:
-            LaunchCommand(Command, WorkingDir)
-            self.CompleteFlag = True
-        except:
-            #
-            # TRICK: hide the output of threads left runing, so that the user can
-            #        catch the error message easily
-            #
-            if not BuildTask._ErrorFlag.isSet():
-                GlobalData.gBuildingModule = "%s [%s, %s, %s]" % (str(self.BuildItem.BuildObject),
-                                                                  self.BuildItem.BuildObject.Arch,
-                                                                  self.BuildItem.BuildObject.ToolChain,
-                                                                  self.BuildItem.BuildObject.BuildTarget
-                                                                 )
-            EdkLogger.SetLevel(EdkLogger.ERROR)
-            BuildTask._ErrorFlag.set()
-            BuildTask._ErrorMessage = "%s broken\n    %s [%s]" % \
-                                      (threading.currentThread().getName(), Command, WorkingDir)
-        # indicate there's a thread is available for another build task
-        BuildTask._RunningQueueLock.acquire()
-        BuildTask._RunningQueue.pop(self.BuildItem)
-        BuildTask._RunningQueueLock.release()
-        BuildTask._Thread.release()
-
-    ## Start build task thread
-    #
-    def Start(self):
-        EdkLogger.quiet("Building ... %s" % repr(self.BuildItem))
-        Command = self.BuildItem.BuildCommand + [self.BuildItem.Target]
-        self.BuildTread = Thread(target=self._CommandThread, args=(Command, self.BuildItem.WorkingDir))
-        self.BuildTread.setName("build thread")
-        self.BuildTread.setDaemon(False)
-        self.BuildTread.start()
-
-## The class implementing the EDK2 build process
-#
-#   The build process includes:
-#       1. Load configuration from target.txt and tools_def.txt in $(WORKSPACE)/Conf
-#       2. Parse DSC file of active platform
-#       3. Parse FDF file if any
-#       4. Establish build database, including parse all other files (module, package)
-#       5. Create AutoGen files (C code file, depex file, makefile) if necessary
-#       6. Call build command
-#
-class Build():
-    ## Constructor
-    #
-    # Constructor will load all necessary configurations, parse platform, modules
-    # and packages and the establish a database for AutoGen.
-    #
-    #   @param  Target              The build command target, one of gSupportedTarget
-    #   @param  WorkspaceDir        The directory of workspace
-    #   @param  Platform            The DSC file of active platform
-    #   @param  Module              The INF file of active module, if any
-    #   @param  Arch                The Arch list of platform or module
-    #   @param  ToolChain           The name list of toolchain
-    #   @param  BuildTarget         The "DEBUG" or "RELEASE" build
-    #   @param  FlashDefinition     The FDF file of active platform
-    #   @param  FdList=[]           The FD names to be individually built
-    #   @param  FvList=[]           The FV names to be individually built
-    #   @param  MakefileType        The type of makefile (for MSFT make or GNU make)
-    #   @param  SilentMode          Indicate multi-thread build mode
-    #   @param  ThreadNumber        The maximum number of thread if in multi-thread build mode
-    #   @param  SkipAutoGen         Skip AutoGen step
-    #   @param  Reparse             Re-parse all meta files
-    #   @param  SkuId               SKU id from command line
-    #
-    def __init__(self, Target, WorkspaceDir, Platform, Module, Arch, ToolChain,
-                 BuildTarget, FlashDefinition, FdList=[], FvList=[],
-                 MakefileType="nmake", SilentMode=False, ThreadNumber=2,
-                 SkipAutoGen=False, Reparse=False, SkuId=None, 
-                 ReportFile=None, ReportType=None):
-
-        self.WorkspaceDir = WorkspaceDir
-        self.Target         = Target
-        self.PlatformFile   = Platform
-        self.ModuleFile     = Module
-        self.ArchList       = Arch
-        self.ToolChainList  = ToolChain
-        self.BuildTargetList= BuildTarget
-        self.Fdf            = FlashDefinition
-        self.FdList         = FdList
-        self.FvList         = FvList
-        self.MakefileType   = MakefileType
-        self.SilentMode     = SilentMode
-        self.ThreadNumber   = ThreadNumber
-        self.SkipAutoGen    = SkipAutoGen
-        self.Reparse        = Reparse
-        self.SkuId          = SkuId
-        self.SpawnMode      = True
-        self.ReportFile     = ReportFile
-        if ReportType == None:
-          self.ReportType   = ['ALL']
-        else:
-          self.ReportType   = ReportType
-
-        self.TargetTxt      = TargetTxtClassObject()
-        self.ToolDef        = ToolDefClassObject()
-        self.Db             = WorkspaceDatabase(None, GlobalData.gGlobalDefines, self.Reparse)
-        #self.Db             = WorkspaceDatabase(None, {}, self.Reparse)
-        self.BuildDatabase  = self.Db.BuildObject
-        self.Platform       = None
-
-        # print dot charater during doing some time-consuming work
-        self.Progress = Utils.Progressor()
-
-        # parse target.txt, tools_def.txt, and platform file
-        #self.RestoreBuildData()
-        self.LoadConfiguration()
-        self.InitBuild()
-
-        # print current build environment and configuration
-        EdkLogger.quiet("%-24s = %s" % ("WORKSPACE", os.environ["WORKSPACE"]))
-        EdkLogger.quiet("%-24s = %s" % ("ECP_SOURCE", os.environ["ECP_SOURCE"]))
-        EdkLogger.quiet("%-24s = %s" % ("EDK_SOURCE", os.environ["EDK_SOURCE"]))
-        EdkLogger.quiet("%-24s = %s" % ("EFI_SOURCE", os.environ["EFI_SOURCE"]))
-        EdkLogger.quiet("%-24s = %s" % ("EDK_TOOLS_PATH", os.environ["EDK_TOOLS_PATH"]))
-
-        EdkLogger.info('\n%-24s = %s' % ("TARGET_ARCH", ' '.join(self.ArchList)))
-        EdkLogger.info('%-24s = %s' % ("TARGET", ' '.join(self.BuildTargetList)))
-        EdkLogger.info('%-24s = %s' % ("TOOL_CHAIN_TAG", ' '.join(self.ToolChainList)))
-
-        EdkLogger.info('\n%-24s = %s' % ("Active Platform", self.PlatformFile))
-
-        if self.Fdf != None and self.Fdf != "":
-            EdkLogger.info('%-24s = %s' % ("Flash Image Definition", self.Fdf))
-
-        if self.ModuleFile != None and self.ModuleFile != "":
-            EdkLogger.info('%-24s = %s' % ("Active Module", self.ModuleFile))
-
-        os.chdir(self.WorkspaceDir)
-        self.Progress.Start("\nProcessing meta-data")
-
-    ## Load configuration
-    #
-    #   This method will parse target.txt and get the build configurations.
-    #
-    def LoadConfiguration(self):
-        #
-        # Check target.txt and tools_def.txt and Init them
-        #
-        BuildConfigurationFile = os.path.normpath(os.path.join(self.WorkspaceDir, gBuildConfiguration))
-        if os.path.isfile(BuildConfigurationFile) == True:
-            StatusCode = self.TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
-
-            ToolDefinitionFile = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
-            if ToolDefinitionFile == '':
-                ToolDefinitionFile = gToolsDefinition
-            ToolDefinitionFile = os.path.normpath(os.path.join(self.WorkspaceDir, ToolDefinitionFile))
-            if os.path.isfile(ToolDefinitionFile) == True:
-                StatusCode = self.ToolDef.LoadToolDefFile(ToolDefinitionFile)
-            else:
-                EdkLogger.error("build", FILE_NOT_FOUND, ExtraData=ToolDefinitionFile)
-        else:
-            EdkLogger.error("build", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)
-
-        # if no ARCH given in command line, get it from target.txt
-        if self.ArchList == None or len(self.ArchList) == 0:
-            self.ArchList = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET_ARCH]
-
-        # if no build target given in command line, get it from target.txt
-        if self.BuildTargetList == None or len(self.BuildTargetList) == 0:
-            self.BuildTargetList = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET]
-
-        # if no tool chain given in command line, get it from target.txt
-        if self.ToolChainList == None or len(self.ToolChainList) == 0:
-            self.ToolChainList = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]
-            if self.ToolChainList == None or len(self.ToolChainList) == 0:
-                EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.\n")
-
-        # check if the tool chains are defined or not
-        NewToolChainList = []
-        for ToolChain in self.ToolChainList:
-            if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG]:
-                EdkLogger.warn("build", "Tool chain [%s] is not defined" % ToolChain)
-            else:
-                NewToolChainList.append(ToolChain)
-        # if no tool chain available, break the build
-        if len(NewToolChainList) == 0:
-            EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
-                            ExtraData="[%s] not defined. No toolchain available for build!\n" % ", ".join(self.ToolChainList))
-        else:
-            self.ToolChainList = NewToolChainList
-
-        if self.ThreadNumber == None:
-            self.ThreadNumber = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER]
-            if self.ThreadNumber == '':
-                self.ThreadNumber = 0
-            else:
-                self.ThreadNumber = int(self.ThreadNumber, 0)
-
-        if self.ThreadNumber == 0:
-            self.ThreadNumber = 1
-
-        if not self.PlatformFile:
-            PlatformFile = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM]
-            if not PlatformFile:
-                # Try to find one in current directory
-                WorkingDirectory = os.getcwd()
-                FileList = glob.glob(os.path.normpath(os.path.join(WorkingDirectory, '*.dsc')))
-                FileNum = len(FileList)
-                if FileNum >= 2:
-                    EdkLogger.error("build", OPTION_MISSING,
-                                    ExtraData="There are %d DSC files in %s. Use '-p' to specify one.\n" % (FileNum, WorkingDirectory))
-                elif FileNum == 1:
-                    PlatformFile = FileList[0]
-                else:
-                    EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
-                                    ExtraData="No active platform specified in target.txt or command line! Nothing can be built.\n")
-
-            self.PlatformFile = PathClass(NormFile(PlatformFile, self.WorkspaceDir), self.WorkspaceDir)
-            ErrorCode, ErrorInfo = self.PlatformFile.Validate(".dsc", False)
-            if ErrorCode != 0:
-                EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo)
-
-    ## Initialize build configuration
-    #
-    #   This method will parse DSC file and merge the configurations from
-    #   command line and target.txt, then get the final build configurations.
-    #
-    def InitBuild(self):
-        ErrorCode, ErrorInfo = self.PlatformFile.Validate(".dsc")
-        if ErrorCode != 0:
-            EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo)
-
-        # create metafile database
-        self.Db.InitDatabase()
-
-        # we need information in platform description file to determine how to build
-        self.Platform = self.BuildDatabase[self.PlatformFile, 'COMMON']
-        if not self.Fdf:
-            self.Fdf = self.Platform.FlashDefinition
-
-        if self.SkuId == None or self.SkuId == '':
-            self.SkuId = self.Platform.SkuName
-
-        # check FD/FV build target
-        if self.Fdf == None or self.Fdf == "":
-            if self.FdList != []:
-                EdkLogger.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self.FdList))
-                self.FdList = []
-            if self.FvList != []:
-                EdkLogger.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self.FvList))
-                self.FvList = []
-        else:
-            FdfParserObj = FdfParser(str(self.Fdf))
-            FdfParserObj.ParseFile()
-            for fvname in self.FvList:
-                if fvname.upper() not in FdfParserObj.Profile.FvDict.keys():
-                    EdkLogger.error("build", OPTION_VALUE_INVALID,
-                                    "No such an FV in FDF file: %s" % fvname)
-
-        #
-        # Merge Arch
-        #
-        if self.ArchList == None or len(self.ArchList) == 0:
-            ArchList = set(self.Platform.SupArchList)
-        else:
-            ArchList = set(self.ArchList) & set(self.Platform.SupArchList)
-        if len(ArchList) == 0:
-            EdkLogger.error("build", PARAMETER_INVALID,
-                            ExtraData = "Active platform supports [%s] only, but [%s] is given."
-                                        % (" ".join(self.Platform.SupArchList), " ".join(self.ArchList)))
-        elif len(ArchList) != len(self.ArchList):
-            SkippedArchList = set(self.ArchList).symmetric_difference(set(self.Platform.SupArchList))
-            EdkLogger.verbose("\nArch [%s] is ignored because active platform supports [%s] but [%s] is specified !"
-                           % (" ".join(SkippedArchList), " ".join(self.Platform.SupArchList), " ".join(self.ArchList)))
-        self.ArchList = tuple(ArchList)
-
-        # Merge build target
-        if self.BuildTargetList == None or len(self.BuildTargetList) == 0:
-            BuildTargetList = self.Platform.BuildTargets
-        else:
-            BuildTargetList = list(set(self.BuildTargetList) & set(self.Platform.BuildTargets))
-        if BuildTargetList == []:
-            EdkLogger.error("build", PARAMETER_INVALID, "Active platform only supports [%s], but [%s] is given"
-                                % (" ".join(self.Platform.BuildTargets), " ".join(self.BuildTargetList)))
-        self.BuildTargetList = BuildTargetList
-
-    ## Build a module or platform
-    #
-    # Create autogen code and makfile for a module or platform, and the launch
-    # "make" command to build it
-    #
-    #   @param  Target                      The target of build command
-    #   @param  Platform                    The platform file
-    #   @param  Module                      The module file
-    #   @param  BuildTarget                 The name of build target, one of "DEBUG", "RELEASE"
-    #   @param  ToolChain                   The name of toolchain to build
-    #   @param  Arch                        The arch of the module/platform
-    #   @param  CreateDepModuleCodeFile     Flag used to indicate creating code
-    #                                       for dependent modules/Libraries
-    #   @param  CreateDepModuleMakeFile     Flag used to indicate creating makefile
-    #                                       for dependent modules/Libraries
-    #
-    def _Build(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True):
-        if AutoGenObject == None:
-            return False
-
-        # skip file generation for cleanxxx targets, run and fds target
-        if Target not in ['clean', 'cleanlib', 'cleanall', 'run', 'fds']:
-            # for target which must generate AutoGen code and makefile
-            if not self.SkipAutoGen or Target == 'genc':
-                self.Progress.Start("Generating code")
-                AutoGenObject.CreateCodeFile(CreateDepsCodeFile)
-                self.Progress.Stop("done!")
-            if Target == "genc":
-                return True
-
-            if not self.SkipAutoGen or Target == 'genmake':
-                self.Progress.Start("Generating makefile")
-                AutoGenObject.CreateMakeFile(CreateDepsMakeFile)
-                self.Progress.Stop("done!")
-            if Target == "genmake":
-                return True
-        else:
-            # always recreate top/platform makefile when clean, just in case of inconsistency
-            AutoGenObject.CreateCodeFile(False)
-            AutoGenObject.CreateMakeFile(False)
-
-        if EdkLogger.GetLevel() == EdkLogger.QUIET:
-            EdkLogger.quiet("Building ... %s" % repr(AutoGenObject))
-
-        BuildCommand = AutoGenObject.BuildCommand
-        if BuildCommand == None or len(BuildCommand) == 0:
-            EdkLogger.error("build", OPTION_MISSING, ExtraData="No MAKE command found for [%s, %s, %s]" % Key)
-
-        BuildCommand = BuildCommand + [Target]
-        LaunchCommand(BuildCommand, AutoGenObject.MakeFileDir)
-        if Target == 'cleanall':
-            try:
-                #os.rmdir(AutoGenObject.BuildDir)
-                RemoveDirectory(AutoGenObject.BuildDir, True)
-            except WindowsError, X:
-                EdkLogger.error("build", FILE_DELETE_FAILURE, ExtraData=str(X))
-        return True
-
-    ## Build active platform for different build targets and different tool chains
-    #
-    def _BuildPlatform(self):
-        for BuildTarget in self.BuildTargetList:
-            for ToolChain in self.ToolChainList:
-                Wa = WorkspaceAutoGen(
-                        self.WorkspaceDir,
-                        self.Platform,
-                        BuildTarget,
-                        ToolChain,
-                        self.ArchList,
-                        self.BuildDatabase,
-                        self.TargetTxt,
-                        self.ToolDef,
-                        self.Fdf,
-                        self.FdList,
-                        self.FvList,
-                        self.SkuId,
-                        self.ReportFile,
-                        self.ReportType
-                        )
-                self.Progress.Stop("done!")
-                self._Build(self.Target, Wa)
-
-    ## Build active module for different build targets, different tool chains and different archs
-    #
-    def _BuildModule(self):
-        for BuildTarget in self.BuildTargetList:
-            for ToolChain in self.ToolChainList:
-                #
-                # module build needs platform build information, so get platform
-                # AutoGen first
-                #
-                Wa = WorkspaceAutoGen(
-                        self.WorkspaceDir,
-                        self.Platform,
-                        BuildTarget,
-                        ToolChain,
-                        self.ArchList,
-                        self.BuildDatabase,
-                        self.TargetTxt,
-                        self.ToolDef,
-                        self.Fdf,
-                        self.FdList,
-                        self.FvList,
-                        self.SkuId,
-                        self.ReportFile,
-                        self.ReportType
-                        )
-                Wa.CreateMakeFile(False)
-                self.Progress.Stop("done!")
-                MaList = []
-                for Arch in self.ArchList:
-                    Ma = ModuleAutoGen(Wa, self.ModuleFile, BuildTarget, ToolChain, Arch, self.PlatformFile)
-                    if Ma == None: continue
-                    MaList.append(Ma)
-                    self._Build(self.Target, Ma)
-                if MaList == []:
-                    EdkLogger.error(
-                                'build',
-                                BUILD_ERROR,
-                                "Module for [%s] is not a component of active platform."\
-                                " Please make sure that the ARCH and inf file path are"\
-                                " given in the same as in [%s]" %\
-                                    (', '.join(self.ArchList), self.Platform),
-                                ExtraData=self.ModuleFile
-                                )
-
-    ## Build a platform in multi-thread mode
-    #
-    def _MultiThreadBuildPlatform(self):
-        for BuildTarget in self.BuildTargetList:
-            for ToolChain in self.ToolChainList:
-                Wa = WorkspaceAutoGen(
-                        self.WorkspaceDir,
-                        self.Platform,
-                        BuildTarget,
-                        ToolChain,
-                        self.ArchList,
-                        self.BuildDatabase,
-                        self.TargetTxt,
-                        self.ToolDef,
-                        self.Fdf,
-                        self.FdList,
-                        self.FvList,
-                        self.SkuId,
-                        self.ReportFile,
-                        self.ReportType
-                        )
-                Wa.CreateMakeFile(False)
-
-                # multi-thread exit flag
-                ExitFlag = threading.Event()
-                ExitFlag.clear()
-                for Arch in self.ArchList:
-                    Pa = PlatformAutoGen(Wa, self.PlatformFile, BuildTarget, ToolChain, Arch)
-                    if Pa == None:
-                        continue
-                    for Module in Pa.Platform.Modules:
-                        # Get ModuleAutoGen object to generate C code file and makefile
-                        Ma = ModuleAutoGen(Wa, Module, BuildTarget, ToolChain, Arch, self.PlatformFile)
-                        if Ma == None:
-                            continue
-                        # Not to auto-gen for targets 'clean', 'cleanlib', 'cleanall', 'run', 'fds'
-                        if self.Target not in ['clean', 'cleanlib', 'cleanall', 'run', 'fds']:
-                            # for target which must generate AutoGen code and makefile
-                            if not self.SkipAutoGen or self.Target == 'genc':
-                                Ma.CreateCodeFile(True)
-                            if self.Target == "genc":
-                                continue
-
-                            if not self.SkipAutoGen or self.Target == 'genmake':
-                                Ma.CreateMakeFile(True)
-                            if self.Target == "genmake":
-                                continue
-                        self.Progress.Stop("done!")
-                        # Generate build task for the module
-                        Bt = BuildTask.New(ModuleMakeUnit(Ma, self.Target))
-                        # Break build if any build thread has error
-                        if BuildTask.HasError():
-                            # we need a full version of makefile for platform
-                            ExitFlag.set()
-                            BuildTask.WaitForComplete()
-                            Pa.CreateMakeFile(False)
-                            EdkLogger.error("build", BUILD_ERROR, "Failed to build module", ExtraData=GlobalData.gBuildingModule)
-                        # Start task scheduler
-                        if not BuildTask.IsOnGoing():
-                            BuildTask.StartScheduler(self.ThreadNumber, ExitFlag)
-
-                    # in case there's an interruption. we need a full version of makefile for platform
-                    Pa.CreateMakeFile(False)
-                    if BuildTask.HasError():
-                        EdkLogger.error("build", BUILD_ERROR, "Failed to build module", ExtraData=GlobalData.gBuildingModule)
-
-                #
-                # All modules have been put in build tasks queue. Tell task scheduler
-                # to exit if all tasks are completed
-                #
-                ExitFlag.set()
-                BuildTask.WaitForComplete()
-
-                #
-                # Check for build error, and raise exception if one
-                # has been signaled.
-                #
-                if BuildTask.HasError():
-                    EdkLogger.error("build", BUILD_ERROR, "Failed to build module", ExtraData=GlobalData.gBuildingModule)
-
-                # Generate FD image if there's a FDF file found
-                if self.Fdf != '' and self.Target in ["", "all", "fds"]:
-                    LaunchCommand(Wa.BuildCommand + ["fds"], Wa.MakeFileDir)
-
-    ## Generate GuidedSectionTools.txt in the FV directories.
-    #
-    def CreateGuidedSectionToolsFile(self):
-        for Arch in self.ArchList:
-            for BuildTarget in self.BuildTargetList:
-                for ToolChain in self.ToolChainList:
-                    FvDir = os.path.join(
-                                self.WorkspaceDir,
-                                self.Platform.OutputDirectory,
-                                '_'.join((BuildTarget, ToolChain)),
-                                'FV'
-                                )
-                    if not os.path.exists(FvDir):
-                        continue
-                    # Build up the list of supported architectures for this build
-                    prefix = '%s_%s_%s_' % (BuildTarget, ToolChain, Arch)
-
-                    # Look through the tool definitions for GUIDed tools
-                    guidAttribs = []
-                    for (attrib, value) in self.ToolDef.ToolsDefTxtDictionary.iteritems():
-                        if attrib.upper().endswith('_GUID'):
-                            split = attrib.split('_')
-                            thisPrefix = '_'.join(split[0:3]) + '_'
-                            if thisPrefix == prefix:
-                                guid = self.ToolDef.ToolsDefTxtDictionary[attrib]
-                                guid = guid.lower()
-                                toolName = split[3]
-                                path = '_'.join(split[0:4]) + '_PATH'
-                                path = self.ToolDef.ToolsDefTxtDictionary[path]
-                                path = self.GetFullPathOfTool(path)
-                                guidAttribs.append((guid, toolName, path))
-
-                    # Write out GuidedSecTools.txt
-                    toolsFile = os.path.join(FvDir, 'GuidedSectionTools.txt')
-                    toolsFile = open(toolsFile, 'wt')
-                    for guidedSectionTool in guidAttribs:
-                        print >> toolsFile, ' '.join(guidedSectionTool)
-                    toolsFile.close()
-
-    ## Returns the full path of the tool.
-    #
-    def GetFullPathOfTool (self, tool):
-        if os.path.exists(tool):
-            return os.path.realpath(tool)
-        else:
-            # We need to search for the tool using the
-            # PATH environment variable.
-            for dirInPath in os.environ['PATH'].split(os.pathsep):
-                foundPath = os.path.join(dirInPath, tool)
-                if os.path.exists(foundPath):
-                    return os.path.realpath(foundPath)
-
-        # If the tool was not found in the path then we just return
-        # the input tool.
-        return tool
-
-    ## Launch the module or platform build
-    #
-    def Launch(self):
-        if self.ModuleFile == None or self.ModuleFile == "":
-            if not self.SpawnMode or self.Target not in ["", "all"]:
-                self.SpawnMode = False
-                self._BuildPlatform()
-            else:
-                self._MultiThreadBuildPlatform()
-            self.CreateGuidedSectionToolsFile()
-        else:
-            self.SpawnMode = False
-            self._BuildModule()
-
-    ## Do some clean-up works when error occurred
-    def Relinquish(self):
-        OldLogLevel = EdkLogger.GetLevel()
-        EdkLogger.SetLevel(EdkLogger.ERROR)
-        #self.DumpBuildData()
-        Utils.Progressor.Abort()
-        if self.SpawnMode == True:
-            BuildTask.Abort()
-        EdkLogger.SetLevel(OldLogLevel)
-
-    def DumpBuildData(self):
-        CacheDirectory = os.path.join(self.WorkspaceDir, gBuildCacheDir)
-        Utils.CreateDirectory(CacheDirectory)
-        Utils.DataDump(Utils.gFileTimeStampCache, os.path.join(CacheDirectory, "gFileTimeStampCache"))
-        Utils.DataDump(Utils.gDependencyDatabase, os.path.join(CacheDirectory, "gDependencyDatabase"))
-
-    def RestoreBuildData(self):
-        FilePath = os.path.join(self.WorkspaceDir, gBuildCacheDir, "gFileTimeStampCache")
-        if Utils.gFileTimeStampCache == {} and os.path.isfile(FilePath):
-            Utils.gFileTimeStampCache = Utils.DataRestore(FilePath)
-            if Utils.gFileTimeStampCache == None:
-                Utils.gFileTimeStampCache = {}
-
-        FilePath = os.path.join(self.WorkspaceDir, gBuildCacheDir, "gDependencyDatabase")
-        if Utils.gDependencyDatabase == {} and os.path.isfile(FilePath):
-            Utils.gDependencyDatabase = Utils.DataRestore(FilePath)
-            if Utils.gDependencyDatabase == None:
-                Utils.gDependencyDatabase = {}
-
-def ParseDefines(DefineList=[]):
-    DefineDict = {}
-    if DefineList != None:
-        for Define in DefineList:
-            DefineTokenList = Define.split("=", 1)
-            if len(DefineTokenList) == 1:
-                DefineDict[DefineTokenList[0]] = ""
-            else:
-                DefineDict[DefineTokenList[0]] = DefineTokenList[1].strip()
-    return DefineDict
-
-gParamCheck = []
-def SingleCheckCallback(option, opt_str, value, parser):
-    if option not in gParamCheck:
-        setattr(parser.values, option.dest, value)
-        gParamCheck.append(option)
-    else:
-        parser.error("Option %s only allows one instance in command line!" % option)
-
-## Parse command line options
-#
-# Using standard Python module optparse to parse command line option of this tool.
-#
-#   @retval Opt   A optparse.Values object containing the parsed options
-#   @retval Args  Target of build command
-#
-def MyOptionParser():
-    Parser = OptionParser(description=__copyright__,version=__version__,prog="build.exe",usage="%prog [options] [all|fds|genc|genmake|clean|cleanall|cleanlib|modules|libraries|run]")
-    Parser.add_option("-a", "--arch", action="append", type="choice", choices=['IA32','X64','IPF','EBC','ARM'], dest="TargetArch",
-        help="ARCHS is one of list: IA32, X64, IPF, ARM or EBC, which overrides target.txt's TARGET_ARCH definition. To specify more archs, please repeat this option.")
-    Parser.add_option("-p", "--platform", action="callback", type="string", dest="PlatformFile", callback=SingleCheckCallback,
-        help="Build the platform specified by the DSC file name argument, overriding target.txt's ACTIVE_PLATFORM definition.")
-    Parser.add_option("-m", "--module", action="callback", type="string", dest="ModuleFile", callback=SingleCheckCallback,
-        help="Build the module specified by the INF file name argument.")
-    Parser.add_option("-b", "--buildtarget", action="append", type="choice", choices=['DEBUG','RELEASE'], dest="BuildTarget",
-        help="BuildTarget is one of list: DEBUG, RELEASE, which overrides target.txt's TARGET definition. To specify more TARGET, please repeat this option.")
-    Parser.add_option("-t", "--tagname", action="append", type="string", dest="ToolChain",
-        help="Using the Tool Chain Tagname to build the platform, overriding target.txt's TOOL_CHAIN_TAG definition.")
-    Parser.add_option("-x", "--sku-id", action="callback", type="string", dest="SkuId", callback=SingleCheckCallback,
-        help="Using this name of SKU ID to build the platform, overriding SKUID_IDENTIFIER in DSC file.")
-
-    Parser.add_option("-n", action="callback", type="int", dest="ThreadNumber", callback=SingleCheckCallback,
-        help="Build the platform using multi-threaded compiler. The value overrides target.txt's MAX_CONCURRENT_THREAD_NUMBER. Less than 2 will disable multi-thread builds.")
-
-    Parser.add_option("-f", "--fdf", action="callback", type="string", dest="FdfFile", callback=SingleCheckCallback,
-        help="The name of the FDF file to use, which overrides the setting in the DSC file.")
-    Parser.add_option("-r", "--rom-image", action="append", type="string", dest="RomImage", default=[],
-        help="The name of FD to be generated. The name must be from [FD] section in FDF file.")
-    Parser.add_option("-i", "--fv-image", action="append", type="string", dest="FvImage", default=[],
-        help="The name of FV to be generated. The name must be from [FV] section in FDF file.")
-
-    Parser.add_option("-u", "--skip-autogen", action="store_true", dest="SkipAutoGen", help="Skip AutoGen step.")
-    Parser.add_option("-e", "--re-parse", action="store_true", dest="Reparse", help="Re-parse all meta-data files.")
-
-    Parser.add_option("-c", "--case-insensitive", action="store_true", dest="CaseInsensitive", help="Don't check case of file name.")
-
-    # Parser.add_option("-D", "--define", action="append", dest="Defines", metavar="NAME[=[VALUE]]",
-    #     help="Define global macro which can be used in DSC/DEC/INF files.")
-
-    Parser.add_option("-w", "--warning-as-error", action="store_true", dest="WarningAsError", help="Treat warning in tools as error.")
-    Parser.add_option("-j", "--log", action="store", dest="LogFile", help="Put log in specified file as well as on console.")
-
-    Parser.add_option("-s", "--silent", action="store_true", type=None, dest="SilentMode",
-        help="Make use of silent mode of (n)make.")
-    Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
-    Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\
-                                                                               "including library instances selected, final dependency expression, "\
-                                                                               "and warning messages, etc.")
-    Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
-    Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")
-
-    Parser.add_option("-y", "--report-file", action="store", dest="ReportFile", help="Create/overwrite the report to the specified filename.")
-    Parser.add_option("-Y", "--report-type", action="append", type="choice", choices=['ALL','PCD',], dest="ReportType",
-        help="Flags that control the type of build report to generate.  Must be one of: [ALL, PCD].  To specify more than one flag, repeat this option on the command line.")
-
-    (Opt, Args)=Parser.parse_args()
-    return (Opt, Args)
-
-## Tool entrance method
-#
-# This method mainly dispatch specific methods per the command line options.
-# If no error found, return zero value so the caller of this tool can know
-# if it's executed successfully or not.
-#
-#   @retval 0     Tool was successful
-#   @retval 1     Tool failed
-#
-def Main():
-    StartTime = time.time()
-
-    # Initialize log system
-    EdkLogger.Initialize()
-
-    #
-    # Parse the options and args
-    #
-    (Option, Target) = MyOptionParser()
-    GlobalData.gOptions = Option
-    GlobalData.gCaseInsensitive = Option.CaseInsensitive
-
-    # Set log level
-    if Option.verbose != None:
-        EdkLogger.SetLevel(EdkLogger.VERBOSE)
-    elif Option.quiet != None:
-        EdkLogger.SetLevel(EdkLogger.QUIET)
-    elif Option.debug != None:
-        EdkLogger.SetLevel(Option.debug + 1)
-    else:
-        EdkLogger.SetLevel(EdkLogger.INFO)
-
-    if Option.LogFile != None:
-        EdkLogger.SetLogFile(Option.LogFile)
-
-    if Option.WarningAsError == True:
-        EdkLogger.SetWarningAsError()
-
-    if platform.platform().find("Windows") >= 0:
-        GlobalData.gIsWindows = True
-    else:
-        GlobalData.gIsWindows = False
-
-    EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[%s]\n" % platform.platform())
-    ReturnCode = 0
-    MyBuild = None
-    try:
-        if len(Target) == 0:
-            Target = "all"
-        elif len(Target) >= 2:
-            EdkLogger.error("build", OPTION_NOT_SUPPORTED, "More than one targets are not supported.",
-                            ExtraData="Please select one of: %s" %(' '.join(gSupportedTarget)))
-        else:
-            Target = Target[0].lower()
-
-        if Target not in gSupportedTarget:
-            EdkLogger.error("build", OPTION_NOT_SUPPORTED, "Not supported target [%s]." % Target,
-                            ExtraData="Please select one of: %s" %(' '.join(gSupportedTarget)))
-
-        GlobalData.gGlobalDefines = ParseDefines(Option.Macros)
-        #
-        # Check environment variable: EDK_TOOLS_PATH, WORKSPACE, PATH
-        #
-        CheckEnvVariable()
-        Workspace = os.getenv("WORKSPACE")
-        #
-        # Get files real name in workspace dir
-        #
-        GlobalData.gAllFiles = Utils.DirCache(Workspace)
-
-        WorkingDirectory = os.getcwd()
-        if not Option.ModuleFile:
-            FileList = glob.glob(os.path.normpath(os.path.join(WorkingDirectory, '*.inf')))
-            FileNum = len(FileList)
-            if FileNum >= 2:
-                EdkLogger.error("build", OPTION_NOT_SUPPORTED, "There are %d INF files in %s." % (FileNum, WorkingDirectory),
-                                ExtraData="Please use '-m <INF_FILE_PATH>' switch to choose one.")
-            elif FileNum == 1:
-                Option.ModuleFile = NormFile(FileList[0], Workspace)
-
-        if Option.ModuleFile:
-            Option.ModuleFile = PathClass(Option.ModuleFile, Workspace)
-            ErrorCode, ErrorInfo = Option.ModuleFile.Validate(".inf", False)
-            if ErrorCode != 0:
-                EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo)
-
-        if Option.PlatformFile != None:
-            Option.PlatformFile = PathClass(Option.PlatformFile, Workspace)
-            ErrorCode, ErrorInfo = Option.PlatformFile.Validate(".dsc", False)
-            if ErrorCode != 0:
-                EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo)
-
-        if Option.FdfFile != None:
-            Option.FdfFile = PathClass(Option.FdfFile, Workspace)
-            ErrorCode, ErrorInfo = Option.FdfFile.Validate(".fdf", False)
-            if ErrorCode != 0:
-                EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo)
-
-        MyBuild = Build(Target, Workspace, Option.PlatformFile, Option.ModuleFile,
-                        Option.TargetArch, Option.ToolChain, Option.BuildTarget,
-                        Option.FdfFile, Option.RomImage, Option.FvImage,
-                        None, Option.SilentMode, Option.ThreadNumber,
-                        Option.SkipAutoGen, Option.Reparse, Option.SkuId, 
-                        Option.ReportFile, Option.ReportType)
-        MyBuild.Launch()
-        #MyBuild.DumpBuildData()
-    except FatalError, X:
-        if MyBuild != None:
-            # for multi-thread build exits safely
-            MyBuild.Relinquish()
-        if Option != None and Option.debug != None:
-            EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
-        ReturnCode = X.args[0]
-    except Warning, X:
-        # error from Fdf parser
-        if MyBuild != None:
-            # for multi-thread build exits safely
-            MyBuild.Relinquish()
-        if Option != None and Option.debug != None:
-            EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
-        else:
-            EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError = False)
-        ReturnCode = FORMAT_INVALID
-    except KeyboardInterrupt:
-        ReturnCode = ABORT_ERROR
-        if Option != None and Option.debug != None:
-            EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
-    except:
-        if MyBuild != None:
-            # for multi-thread build exits safely
-            MyBuild.Relinquish()
-
-        # try to get the meta-file from the object causing exception
-        Tb = sys.exc_info()[-1]
-        MetaFile = GlobalData.gProcessingFile
-        while Tb != None:
-            if 'self' in Tb.tb_frame.f_locals and hasattr(Tb.tb_frame.f_locals['self'], 'MetaFile'):
-                MetaFile = Tb.tb_frame.f_locals['self'].MetaFile
-            Tb = Tb.tb_next
-        EdkLogger.error(
-                    "\nbuild",
-                    CODE_ERROR,
-                    "Unknown fatal error when processing [%s]" % MetaFile,
-                    ExtraData="\n(Please send email to dev@buildtools.tianocore.org for help, attaching following call stack trace!)\n",
-                    RaiseError=False
-                    )
-        EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
-        ReturnCode = CODE_ERROR
-    finally:
-        Utils.Progressor.Abort()
-
-    if MyBuild != None:
-        MyBuild.Db.Close()
-
-    if ReturnCode == 0:
-        Conclusion = "Done"
-    elif ReturnCode == ABORT_ERROR:
-        Conclusion = "Aborted"
-    else:
-        Conclusion = "Failed"
-    FinishTime = time.time()
-    BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime))))
-    EdkLogger.SetLevel(EdkLogger.QUIET)
-    EdkLogger.quiet("\n- %s -\n%s [%s]" % (Conclusion, time.strftime("%H:%M:%S, %b.%d %Y", time.localtime()), BuildDuration))
-
-    return ReturnCode
-
-if __name__ == '__main__':
-    r = Main()
-    ## 0-127 is a safe return range, and 1 is a standard default error
-    if r < 0 or r > 127: r = 1
-    sys.exit(r)
-
+## @file\r
+# build a platform or a module\r
+#\r
+#  Copyright (c) 2007 - 2010, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+##\r
+# Import Modules\r
+#\r
+import os\r
+import re\r
+import sys\r
+import glob\r
+import time\r
+import platform\r
+import traceback\r
+\r
+from threading import *\r
+from optparse import OptionParser\r
+from subprocess import *\r
+from Common import Misc as Utils\r
+\r
+from Common.TargetTxtClassObject import *\r
+from Common.ToolDefClassObject import *\r
+from Common.DataType import *\r
+from AutoGen.AutoGen import *\r
+from Common.BuildToolError import *\r
+from Workspace.WorkspaceDatabase import *\r
+\r
+from BuildReport import BuildReport\r
+\r
+import Common.EdkLogger\r
+import Common.GlobalData as GlobalData\r
+\r
+# Version and Copyright\r
+VersionNumber = "0.5"\r
+__version__ = "%prog Version " + VersionNumber\r
+__copyright__ = "Copyright (c) 2007 - 2010, Intel Corporation  All rights reserved."\r
+\r
+## standard targets of build command\r
+gSupportedTarget = ['all', 'genc', 'genmake', 'modules', 'libraries', 'fds', 'clean', 'cleanall', 'cleanlib', 'run']\r
+\r
+## build configuration file\r
+gBuildConfiguration = "Conf/target.txt"\r
+gBuildCacheDir = "Conf/.cache"\r
+gToolsDefinition = "Conf/tools_def.txt"\r
+\r
+## Check environment PATH variable to make sure the specified tool is found\r
+#\r
+#   If the tool is found in the PATH, then True is returned\r
+#   Otherwise, False is returned\r
+#\r
+def IsToolInPath(tool):\r
+    if os.environ.has_key('PATHEXT'):\r
+        extns = os.environ['PATHEXT'].split(os.path.pathsep)\r
+    else:\r
+        extns = ('',)\r
+    for pathDir in os.environ['PATH'].split(os.path.pathsep):\r
+        for ext in extns:\r
+            if os.path.exists(os.path.join(pathDir, tool + ext)):\r
+                return True\r
+    return False\r
+\r
+## Check environment variables\r
+#\r
+#  Check environment variables that must be set for build. Currently they are\r
+#\r
+#   WORKSPACE           The directory all packages/platforms start from\r
+#   EDK_TOOLS_PATH      The directory contains all tools needed by the build\r
+#   PATH                $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH\r
+#\r
+#   If any of above environment variable is not set or has error, the build\r
+#   will be broken.\r
+#\r
+def CheckEnvVariable():\r
+    # check WORKSPACE\r
+    if "WORKSPACE" not in os.environ:\r
+        EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",\r
+                        ExtraData="WORKSPACE")\r
+\r
+    WorkspaceDir = os.path.normcase(os.path.normpath(os.environ["WORKSPACE"]))\r
+    if not os.path.exists(WorkspaceDir):\r
+        EdkLogger.error("build", FILE_NOT_FOUND, "WORKSPACE doesn't exist", ExtraData="%s" % WorkspaceDir)\r
+    elif ' ' in WorkspaceDir:\r
+        EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in WORKSPACE path",\r
+                        ExtraData=WorkspaceDir)\r
+    os.environ["WORKSPACE"] = WorkspaceDir\r
+\r
+    #\r
+    # Check EFI_SOURCE (R8 build convention). EDK_SOURCE will always point to ECP\r
+    #\r
+    os.environ["ECP_SOURCE"] = os.path.join(WorkspaceDir, GlobalData.gEdkCompatibilityPkg)\r
+    if "EFI_SOURCE" not in os.environ:\r
+        os.environ["EFI_SOURCE"] = os.environ["ECP_SOURCE"]\r
+    if "EDK_SOURCE" not in os.environ:\r
+        os.environ["EDK_SOURCE"] = os.environ["ECP_SOURCE"]\r
+\r
+    #\r
+    # Unify case of characters on case-insensitive systems\r
+    #\r
+    EfiSourceDir = os.path.normcase(os.path.normpath(os.environ["EFI_SOURCE"]))\r
+    EdkSourceDir = os.path.normcase(os.path.normpath(os.environ["EDK_SOURCE"]))\r
+    EcpSourceDir = os.path.normcase(os.path.normpath(os.environ["ECP_SOURCE"]))\r
\r
+    os.environ["EFI_SOURCE"] = EfiSourceDir\r
+    os.environ["EDK_SOURCE"] = EdkSourceDir\r
+    os.environ["ECP_SOURCE"] = EcpSourceDir\r
+    os.environ["EDK_TOOLS_PATH"] = os.path.normcase(os.environ["EDK_TOOLS_PATH"])\r
+    \r
+    if not os.path.exists(EcpSourceDir):\r
+        EdkLogger.verbose("ECP_SOURCE = %s doesn't exist. R8 modules could not be built." % EcpSourceDir)\r
+    elif ' ' in EcpSourceDir:\r
+        EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in ECP_SOURCE path",\r
+                        ExtraData=EcpSourceDir)\r
+    if not os.path.exists(EdkSourceDir):\r
+        if EdkSourceDir == EcpSourceDir:\r
+            EdkLogger.verbose("EDK_SOURCE = %s doesn't exist. R8 modules could not be built." % EdkSourceDir)\r
+        else:\r
+            EdkLogger.error("build", PARAMETER_INVALID, "EDK_SOURCE does not exist",\r
+                            ExtraData=EdkSourceDir)\r
+    elif ' ' in EdkSourceDir:\r
+        EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in EDK_SOURCE path",\r
+                        ExtraData=EdkSourceDir)\r
+    if not os.path.exists(EfiSourceDir):\r
+        if EfiSourceDir == EcpSourceDir:\r
+            EdkLogger.verbose("EFI_SOURCE = %s doesn't exist. R8 modules could not be built." % EfiSourceDir)\r
+        else:\r
+            EdkLogger.error("build", PARAMETER_INVALID, "EFI_SOURCE does not exist",\r
+                            ExtraData=EfiSourceDir)\r
+    elif ' ' in EfiSourceDir:\r
+        EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in EFI_SOURCE path",\r
+                        ExtraData=EfiSourceDir)\r
+\r
+    # change absolute path to relative path to WORKSPACE\r
+    if EfiSourceDir.upper().find(WorkspaceDir.upper()) != 0:\r
+        EdkLogger.error("build", PARAMETER_INVALID, "EFI_SOURCE is not under WORKSPACE",\r
+                        ExtraData="WORKSPACE = %s\n    EFI_SOURCE = %s" % (WorkspaceDir, EfiSourceDir))\r
+    if EdkSourceDir.upper().find(WorkspaceDir.upper()) != 0:\r
+        EdkLogger.error("build", PARAMETER_INVALID, "EDK_SOURCE is not under WORKSPACE",\r
+                        ExtraData="WORKSPACE = %s\n    EDK_SOURCE = %s" % (WorkspaceDir, EdkSourceDir))\r
+    if EcpSourceDir.upper().find(WorkspaceDir.upper()) != 0:\r
+        EdkLogger.error("build", PARAMETER_INVALID, "ECP_SOURCE is not under WORKSPACE",\r
+                        ExtraData="WORKSPACE = %s\n    ECP_SOURCE = %s" % (WorkspaceDir, EcpSourceDir))\r
+\r
+    # check EDK_TOOLS_PATH\r
+    if "EDK_TOOLS_PATH" not in os.environ:\r
+        EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",\r
+                        ExtraData="EDK_TOOLS_PATH")\r
+\r
+    # check PATH\r
+    if "PATH" not in os.environ:\r
+        EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",\r
+                        ExtraData="PATH")\r
+\r
+    GlobalData.gWorkspace = WorkspaceDir\r
+    GlobalData.gEfiSource = EfiSourceDir\r
+    GlobalData.gEdkSource = EdkSourceDir\r
+    GlobalData.gEcpSource = EcpSourceDir\r
+\r
+## Get normalized file path\r
+#\r
+# Convert the path to be local format, and remove the WORKSPACE path at the\r
+# beginning if the file path is given in full path.\r
+#\r
+# @param  FilePath      File path to be normalized\r
+# @param  Workspace     Workspace path which the FilePath will be checked against\r
+#\r
+# @retval string        The normalized file path\r
+#\r
+def NormFile(FilePath, Workspace):\r
+    # check if the path is absolute or relative\r
+    if os.path.isabs(FilePath):\r
+        FileFullPath = os.path.normpath(FilePath)\r
+    else:\r
+        FileFullPath = os.path.normpath(os.path.join(Workspace, FilePath))\r
+\r
+    # check if the file path exists or not\r
+    if not os.path.isfile(FileFullPath):\r
+        EdkLogger.error("build", FILE_NOT_FOUND, ExtraData="\t%s (Please give file in absolute path or relative to WORKSPACE)"  % FileFullPath)\r
+\r
+    # remove workspace directory from the beginning part of the file path\r
+    if Workspace[-1] in ["\\", "/"]:\r
+        return FileFullPath[len(Workspace):]\r
+    else:\r
+        return FileFullPath[(len(Workspace) + 1):]\r
+\r
+## Get the output of an external program\r
+#\r
+# This is the entrance method of thread reading output of an external program and\r
+# putting them in STDOUT/STDERR of current program.\r
+#\r
+# @param  From      The stream message read from\r
+# @param  To        The stream message put on\r
+# @param  ExitFlag  The flag used to indicate stopping reading\r
+#\r
+def ReadMessage(From, To, ExitFlag):\r
+    while True:\r
+        # read one line a time\r
+        Line = From.readline()\r
+        # empty string means "end"\r
+        if Line != None and Line != "":\r
+            To(Line.rstrip())\r
+        else:\r
+            break\r
+        if ExitFlag.isSet():\r
+            break\r
+\r
+## Launch an external program\r
+#\r
+# This method will call subprocess.Popen to execute an external program with\r
+# given options in specified directory. Because of the dead-lock issue during\r
+# redirecting output of the external program, threads are used to to do the\r
+# redirection work.\r
+#\r
+# @param  Command               A list or string containing the call of the program\r
+# @param  WorkingDir            The directory in which the program will be running\r
+#\r
+def LaunchCommand(Command, WorkingDir):\r
+    # if working directory doesn't exist, Popen() will raise an exception\r
+    if not os.path.isdir(WorkingDir):\r
+        EdkLogger.error("build", FILE_NOT_FOUND, ExtraData=WorkingDir)\r
+\r
+    Proc = None\r
+    EndOfProcedure = None\r
+    try:\r
+        # launch the command\r
+        Proc = Popen(Command, stdout=PIPE, stderr=PIPE, env=os.environ, cwd=WorkingDir, bufsize=-1)\r
+\r
+        # launch two threads to read the STDOUT and STDERR\r
+        EndOfProcedure = Event()\r
+        EndOfProcedure.clear()\r
+        if Proc.stdout:\r
+            StdOutThread = Thread(target=ReadMessage, args=(Proc.stdout, EdkLogger.info, EndOfProcedure))\r
+            StdOutThread.setName("STDOUT-Redirector")\r
+            StdOutThread.setDaemon(False)\r
+            StdOutThread.start()\r
+\r
+        if Proc.stderr:\r
+            StdErrThread = Thread(target=ReadMessage, args=(Proc.stderr, EdkLogger.quiet, EndOfProcedure))\r
+            StdErrThread.setName("STDERR-Redirector")\r
+            StdErrThread.setDaemon(False)\r
+            StdErrThread.start()\r
+\r
+        # waiting for program exit\r
+        Proc.wait()\r
+    except: # in case of aborting\r
+        # terminate the threads redirecting the program output\r
+        if EndOfProcedure != None:\r
+            EndOfProcedure.set()\r
+        if Proc == None:\r
+            if type(Command) != type(""):\r
+                Command = " ".join(Command)\r
+            EdkLogger.error("build", COMMAND_FAILURE, "Failed to start command", ExtraData="%s [%s]" % (Command, WorkingDir))\r
+\r
+    if Proc.stdout:\r
+        StdOutThread.join()\r
+    if Proc.stderr:\r
+        StdErrThread.join()\r
+\r
+    # check the return code of the program\r
+    if Proc.returncode != 0:\r
+        if type(Command) != type(""):\r
+            Co