]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
BaseTools: Cleanup unneeded code
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GenFdsGlobalVariable.py
index 236283751e1ac0aa264a862e06e2d23034fd3c85..c2e82de891d3594cc08cfbcd769f476200455762 100644 (file)
-## @file
-# Global variables for GenFds
-#
-#  Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
-#
-#  This program and the accompanying materials
-#  are licensed and made available under the terms and conditions of the BSD License
-#  which accompanies this distribution.  The full text of the license may be found at
-#  http://opensource.org/licenses/bsd-license.php
-#
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-
-##
-# Import Modules
-#
-import os
-import sys
-import subprocess
-import struct
-import array
-
-from Common.BuildToolError import *
-from Common import EdkLogger
-from Common.Misc import SaveFileOnChange
-
-from Common.TargetTxtClassObject import TargetTxtClassObject
-from Common.ToolDefClassObject import ToolDefClassObject
-from AutoGen.BuildEngine import BuildRule
-import Common.DataType as DataType
-from Common.Misc import PathClass
-
-## Global variables
-#
-#
-class GenFdsGlobalVariable:
-    FvDir = ''
-    OutputDirDict = {}
-    BinDir = ''
-    # will be FvDir + os.sep + 'Ffs'
-    FfsDir = ''
-    FdfParser = None
-    LibDir = ''
-    WorkSpace = None
-    WorkSpaceDir = ''
-    EdkSourceDir = ''
-    OutputDirFromDscDict = {}
-    TargetName = ''
-    ToolChainTag = ''
-    RuleDict = {}
-    ArchList = None
-    VtfDict = {}
-    ActivePlatform = None
-    FvAddressFileName = ''
-    VerboseMode = False
-    DebugLevel = -1
-    SharpCounter = 0
-    SharpNumberPerLine = 40
-    FdfFile = ''
-    FdfFileTimeStamp = 0
-    FixedLoadAddress = False
-    PlatformName = ''
-    
-    BuildRuleFamily = "MSFT"
-    ToolChainFamily = "MSFT"
-    __BuildRuleDatabase = None
-
-    SectionHeader = struct.Struct("3B 1B")
-    
-    ## LoadBuildRule
-    #
-    @staticmethod
-    def __LoadBuildRule():
-        if GenFdsGlobalVariable.__BuildRuleDatabase:
-            return GenFdsGlobalVariable.__BuildRuleDatabase
-        BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, "Conf/target.txt"))
-        TargetTxt = TargetTxtClassObject()
-        if os.path.isfile(BuildConfigurationFile) == True:
-            TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
-            if DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF in TargetTxt.TargetTxtDictionary:
-                BuildRuleFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF]
-            if BuildRuleFile in [None, '']:
-                BuildRuleFile = 'Conf/build_rule.txt'
-            GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule(BuildRuleFile)
-            ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
-            if ToolDefinitionFile == '':
-                ToolDefinitionFile = "Conf/tools_def.txt"
-            if os.path.isfile(ToolDefinitionFile):
-                ToolDef = ToolDefClassObject()
-                ToolDef.LoadToolDefFile(ToolDefinitionFile)
-                ToolDefinition = ToolDef.ToolsDefTxtDatabase
-                if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \
-                   and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \
-                   and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:
-                    GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]
-                    
-                if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \
-                   and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \
-                   and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:
-                    GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]
-        return GenFdsGlobalVariable.__BuildRuleDatabase
-
-    ## GetBuildRules
-    #    @param Inf: object of InfBuildData
-    #    @param Arch: current arch
-    #
-    @staticmethod
-    def GetBuildRules(Inf, Arch):
-        if not Arch:
-            Arch = 'COMMON'
-
-        if not Arch in GenFdsGlobalVariable.OutputDirDict:
-            return {}
-
-        BuildRuleDatabase = GenFdsGlobalVariable.__LoadBuildRule()
-        if not BuildRuleDatabase:
-            return {}
-
-        PathClassObj = PathClass(str(Inf.MetaFile).lstrip(GenFdsGlobalVariable.WorkSpaceDir),
-                                 GenFdsGlobalVariable.WorkSpaceDir)
-        Macro = {}
-        Macro["WORKSPACE"             ] = GenFdsGlobalVariable.WorkSpaceDir
-        Macro["MODULE_NAME"           ] = Inf.BaseName
-        Macro["MODULE_GUID"           ] = Inf.Guid
-        Macro["MODULE_VERSION"        ] = Inf.Version
-        Macro["MODULE_TYPE"           ] = Inf.ModuleType
-        Macro["MODULE_FILE"           ] = str(PathClassObj)
-        Macro["MODULE_FILE_BASE_NAME" ] = PathClassObj.BaseName
-        Macro["MODULE_RELATIVE_DIR"   ] = PathClassObj.SubDir
-        Macro["MODULE_DIR"            ] = PathClassObj.SubDir
-
-        Macro["BASE_NAME"             ] = Inf.BaseName
-
-        Macro["ARCH"                  ] = Arch
-        Macro["TOOLCHAIN"             ] = GenFdsGlobalVariable.ToolChainTag
-        Macro["TOOLCHAIN_TAG"         ] = GenFdsGlobalVariable.ToolChainTag
-        Macro["TARGET"                ] = GenFdsGlobalVariable.TargetName
-
-        Macro["BUILD_DIR"             ] = GenFdsGlobalVariable.OutputDirDict[Arch]
-        Macro["BIN_DIR"               ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)
-        Macro["LIB_DIR"               ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)
-        BuildDir = os.path.join(
-            GenFdsGlobalVariable.OutputDirDict[Arch],
-            Arch,
-            PathClassObj.SubDir,
-            PathClassObj.BaseName
-        )
-        Macro["MODULE_BUILD_DIR"      ] = BuildDir
-        Macro["OUTPUT_DIR"            ] = os.path.join(BuildDir, "OUTPUT")
-        Macro["DEBUG_DIR"             ] = os.path.join(BuildDir, "DEBUG")
-
-        BuildRules = {}
-        for Type in BuildRuleDatabase.FileTypeList:
-            #first try getting build rule by BuildRuleFamily
-            RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
-            if not RuleObject:
-                # build type is always module type, but ...
-                if Inf.ModuleType != Inf.BuildType:
-                    RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
-            #second try getting build rule by ToolChainFamily
-            if not RuleObject:
-                RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]
-                if not RuleObject:
-                    # build type is always module type, but ...
-                    if Inf.ModuleType != Inf.BuildType:
-                        RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]
-            if not RuleObject:
-                continue
-            RuleObject = RuleObject.Instantiate(Macro)
-            BuildRules[Type] = RuleObject
-            for Ext in RuleObject.SourceFileExtList:
-                BuildRules[Ext] = RuleObject
-        return BuildRules
-
-    ## GetModuleCodaTargetList
-    #
-    #    @param Inf: object of InfBuildData
-    #    @param Arch: current arch
-    #
-    @staticmethod
-    def GetModuleCodaTargetList(Inf, Arch):
-        BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)
-        if not BuildRules:
-            return []
-
-        TargetList = set()
-        FileList = []
-        for File in Inf.Sources:
-            if File.TagName in ("", "*", GenFdsGlobalVariable.ToolChainTag) and \
-                File.ToolChainFamily in ("", "*", GenFdsGlobalVariable.ToolChainFamily):
-                FileList.append((File, DataType.TAB_UNKNOWN_FILE))
-        
-        for File in Inf.Binaries:
-            if File.Target in ['COMMON', '*', GenFdsGlobalVariable.TargetName]:
-                FileList.append((File, File.Type))
-
-        for File, FileType in FileList:
-            LastTarget = None
-            RuleChain = []
-            SourceList = [File]
-            Index = 0
-            while Index < len(SourceList):
-                Source = SourceList[Index]
-                Index = Index + 1
-    
-                if File.IsBinary and File == Source and Inf.Binaries != None and File in Inf.Binaries:
-                    # Skip all files that are not binary libraries
-                    if not Inf.LibraryClass:
-                        continue            
-                    RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE]
-                elif FileType in BuildRules:
-                    RuleObject = BuildRules[FileType]
-                elif Source.Ext in BuildRules:
-                    RuleObject = BuildRules[Source.Ext]
-                else:
-                    # stop at no more rules
-                    if LastTarget:
-                        TargetList.add(str(LastTarget))
-                    break
-    
-                FileType = RuleObject.SourceFileType
-    
-                # stop at STATIC_LIBRARY for library
-                if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:
-                    if LastTarget:
-                        TargetList.add(str(LastTarget))
-                    break
-    
-                Target = RuleObject.Apply(Source)
-                if not Target:
-                    if LastTarget:
-                        TargetList.add(str(LastTarget))
-                    break
-                elif not Target.Outputs:
-                    # Only do build for target with outputs
-                    TargetList.add(str(Target))
-    
-                # to avoid cyclic rule
-                if FileType in RuleChain:
-                    break
-    
-                RuleChain.append(FileType)
-                SourceList.extend(Target.Outputs)
-                LastTarget = Target
-                FileType = DataType.TAB_UNKNOWN_FILE
-
-        return list(TargetList)
-
-    ## SetDir()
-    #
-    #   @param  OutputDir           Output directory
-    #   @param  FdfParser           FDF contents parser
-    #   @param  Workspace           The directory of workspace
-    #   @param  ArchList            The Arch list of platform
-    #
-    def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):
-        GenFdsGlobalVariable.VerboseLogger( "GenFdsGlobalVariable.OutputDir :%s" %OutputDir)
-#        GenFdsGlobalVariable.OutputDirDict = OutputDir
-        GenFdsGlobalVariable.FdfParser = FdfParser
-        GenFdsGlobalVariable.WorkSpace = WorkSpace
-        GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV')
-        if not os.path.exists(GenFdsGlobalVariable.FvDir) :
-            os.makedirs(GenFdsGlobalVariable.FvDir)
-        GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
-        if not os.path.exists(GenFdsGlobalVariable.FfsDir) :
-            os.makedirs(GenFdsGlobalVariable.FfsDir)
-        if ArchList != None:
-            GenFdsGlobalVariable.ArchList = ArchList
-
-        T_CHAR_LF = '\n'
-        #
-        # Create FV Address inf file
-        #
-        GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')
-        FvAddressFile = open (GenFdsGlobalVariable.FvAddressFileName, 'w')
-        #
-        # Add [Options]
-        #
-        FvAddressFile.writelines("[options]" + T_CHAR_LF)
-        BsAddress = '0'
-        for Arch in ArchList:
-            if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress:
-                BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress
-                break
-
-        FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
-                                       BsAddress          + \
-                                       T_CHAR_LF)
-
-        RtAddress = '0'
-        for Arch in ArchList:
-            if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress:
-                RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress
-
-        FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
-                                       RtAddress          + \
-                                       T_CHAR_LF)
-
-        FvAddressFile.close()
-
-    ## ReplaceWorkspaceMacro()
-    #
-    #   @param  String           String that may contain macro
-    #
-    def ReplaceWorkspaceMacro(String):
-        Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)
-        if os.path.exists(Str):
-            if not os.path.isabs(Str):
-                Str = os.path.abspath(Str)
-        else:
-            Str = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, String)
-        return os.path.normpath(Str)
-
-    ## Check if the input files are newer than output files
-    #
-    #   @param  Output          Path of output file
-    #   @param  Input           Path list of input files
-    #
-    #   @retval True            if Output doesn't exist, or any Input is newer
-    #   @retval False           if all Input is older than Output
-    #
-    @staticmethod
-    def NeedsUpdate(Output, Input):
-        if not os.path.exists(Output):
-            return True
-        # always update "Output" if no "Input" given
-        if Input == None or len(Input) == 0:
-            return True
-
-        # if fdf file is changed after the 'Output" is generated, update the 'Output'
-        OutputTime = os.path.getmtime(Output)
-        if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:
-            return True
-
-        for F in Input:
-            # always update "Output" if any "Input" doesn't exist
-            if not os.path.exists(F):
-                return True
-            # always update "Output" if any "Input" is newer than "Output"
-            if os.path.getmtime(F) > OutputTime:
-                return True
-        return False
-
-    @staticmethod
-    def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
-                        GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None):
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
-            return
-        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
-
-        Cmd = ["GenSec"]
-        if Type not in [None, '']:
-            Cmd += ["-s", Type]
-        if CompressionType not in [None, '']:
-            Cmd += ["-c", CompressionType]
-        if Guid != None:
-            Cmd += ["-g", Guid]
-        if GuidHdrLen not in [None, '']:
-            Cmd += ["-l", GuidHdrLen]
-        if len(GuidAttr) != 0:
-            #Add each guided attribute
-            for Attr in GuidAttr:
-                Cmd += ["-r", Attr]
-        if InputAlign != None:
-            #Section Align is only for dummy section without section type
-            for SecAlign in InputAlign:
-                Cmd += ["--sectionalign", SecAlign]
-
-        if Ui not in [None, '']:
-            #Cmd += ["-n", '"' + Ui + '"']
-            SectionData = array.array('B', [0,0,0,0])
-            SectionData.fromstring(Ui.encode("utf_16_le"))
-            SectionData.append(0)
-            SectionData.append(0)
-            Len = len(SectionData)
-            GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)
-            SaveFileOnChange(Output,  SectionData.tostring())
-        elif Ver not in [None, '']:
-            #Cmd += ["-j", Ver]
-            SectionData = array.array('B', [0,0,0,0])
-            SectionData.fromstring(Ver.encode("utf_16_le"))
-            SectionData.append(0)
-            SectionData.append(0)
-            Len = len(SectionData)
-            GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x14)
-            SaveFileOnChange(Output,  SectionData.tostring())
-        else:
-            Cmd += ["-o", Output]
-            Cmd += Input
-            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
-
-    @staticmethod
-    def GetAlignment (AlignString):
-        if AlignString == None:
-            return 0
-        if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K"):\r
+## @file\r
+# Global variables for GenFds\r
+#\r
+#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  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 Common.LongFilePathOs as os\r
+import sys\r
+import subprocess\r
+import struct\r
+import array\r
+\r
+from Common.BuildToolError import *\r
+from Common import EdkLogger\r
+from Common.Misc import SaveFileOnChange\r
+\r
+from Common.TargetTxtClassObject import TargetTxtClassObject\r
+from Common.ToolDefClassObject import ToolDefClassObject\r
+from AutoGen.BuildEngine import BuildRule\r
+import Common.DataType as DataType\r
+from Common.Misc import PathClass\r
+from Common.LongFilePathSupport import OpenLongFilePath as open\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
+\r
+## Global variables\r
+#\r
+#\r
+class GenFdsGlobalVariable:\r
+    FvDir = ''\r
+    OutputDirDict = {}\r
+    BinDir = ''\r
+    # will be FvDir + os.sep + 'Ffs'\r
+    FfsDir = ''\r
+    FdfParser = None\r
+    LibDir = ''\r
+    WorkSpace = None\r
+    WorkSpaceDir = ''\r
+    ConfDir = ''\r
+    EdkSourceDir = ''\r
+    OutputDirFromDscDict = {}\r
+    TargetName = ''\r
+    ToolChainTag = ''\r
+    RuleDict = {}\r
+    ArchList = None\r
+    VtfDict = {}\r
+    ActivePlatform = None\r
+    FvAddressFileName = ''\r
+    VerboseMode = False\r
+    DebugLevel = -1\r
+    SharpCounter = 0\r
+    SharpNumberPerLine = 40\r
+    FdfFile = ''\r
+    FdfFileTimeStamp = 0\r
+    FixedLoadAddress = False\r
+    PlatformName = ''\r
+    \r
+    BuildRuleFamily = "MSFT"\r
+    ToolChainFamily = "MSFT"\r
+    __BuildRuleDatabase = None\r
+    GuidToolDefinition = {}\r
+    FfsCmdDict = {}\r
+    SecCmdList = []\r
+    CopyList   = []\r
+    ModuleFile = ''\r
+    EnableGenfdsMultiThread = False\r
+    \r
+    #\r
+    # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.\r
+    # At the beginning of each generation of FV, false flag is appended to the list,\r
+    # after the call to GenerateSection returns, check the size of the output file,\r
+    # if it is greater than 0xFFFFFF, the tail flag in list is set to true,\r
+    # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.\r
+    # At the end of generation of FV, pop the flag.\r
+    # List is used as a stack to handle nested FV generation.\r
+    #\r
+    LargeFileInFvFlags = []\r
+    EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'\r
+    LARGE_FILE_SIZE = 0x1000000\r
+\r
+    SectionHeader = struct.Struct("3B 1B")\r
+    \r
+    ## LoadBuildRule\r
+    #\r
+    @staticmethod\r
+    def __LoadBuildRule():\r
+        if GenFdsGlobalVariable.__BuildRuleDatabase:\r
+            return GenFdsGlobalVariable.__BuildRuleDatabase\r
+        BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.ConfDir, "target.txt"))\r
+        TargetTxt = TargetTxtClassObject()\r
+        if os.path.isfile(BuildConfigurationFile) == True:\r
+            TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
+            if DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF in TargetTxt.TargetTxtDictionary:\r
+                BuildRuleFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
+            if not BuildRuleFile:\r
+                BuildRuleFile = 'Conf/build_rule.txt'\r
+            GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule(BuildRuleFile)\r
+            ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
+            if ToolDefinitionFile == '':\r
+                ToolDefinitionFile = "Conf/tools_def.txt"\r
+            if os.path.isfile(ToolDefinitionFile):\r
+                ToolDef = ToolDefClassObject()\r
+                ToolDef.LoadToolDefFile(ToolDefinitionFile)\r
+                ToolDefinition = ToolDef.ToolsDefTxtDatabase\r
+                if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \\r
+                   and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \\r
+                   and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:\r
+                    GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]\r
+                    \r
+                if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \\r
+                   and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \\r
+                   and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:\r
+                    GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]\r
+        return GenFdsGlobalVariable.__BuildRuleDatabase\r
+\r
+    ## GetBuildRules\r
+    #    @param Inf: object of InfBuildData\r
+    #    @param Arch: current arch\r
+    #\r
+    @staticmethod\r
+    def GetBuildRules(Inf, Arch):\r
+        if not Arch:\r
+            Arch = DataType.TAB_COMMON\r
+\r
+        if not Arch in GenFdsGlobalVariable.OutputDirDict:\r
+            return {}\r
+\r
+        BuildRuleDatabase = GenFdsGlobalVariable.__LoadBuildRule()\r
+        if not BuildRuleDatabase:\r
+            return {}\r
+\r
+        PathClassObj = PathClass(Inf.MetaFile.File,\r
+                                 GenFdsGlobalVariable.WorkSpaceDir)\r
+        Macro = {}\r
+        Macro["WORKSPACE"             ] = GenFdsGlobalVariable.WorkSpaceDir\r
+        Macro["MODULE_NAME"           ] = Inf.BaseName\r
+        Macro["MODULE_GUID"           ] = Inf.Guid\r
+        Macro["MODULE_VERSION"        ] = Inf.Version\r
+        Macro["MODULE_TYPE"           ] = Inf.ModuleType\r
+        Macro["MODULE_FILE"           ] = str(PathClassObj)\r
+        Macro["MODULE_FILE_BASE_NAME" ] = PathClassObj.BaseName\r
+        Macro["MODULE_RELATIVE_DIR"   ] = PathClassObj.SubDir\r
+        Macro["MODULE_DIR"            ] = PathClassObj.SubDir\r
+\r
+        Macro["BASE_NAME"             ] = Inf.BaseName\r
+\r
+        Macro["ARCH"                  ] = Arch\r
+        Macro["TOOLCHAIN"             ] = GenFdsGlobalVariable.ToolChainTag\r
+        Macro["TOOLCHAIN_TAG"         ] = GenFdsGlobalVariable.ToolChainTag\r
+        Macro["TOOL_CHAIN_TAG"        ] = GenFdsGlobalVariable.ToolChainTag\r
+        Macro["TARGET"                ] = GenFdsGlobalVariable.TargetName\r
+\r
+        Macro["BUILD_DIR"             ] = GenFdsGlobalVariable.OutputDirDict[Arch]\r
+        Macro["BIN_DIR"               ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)\r
+        Macro["LIB_DIR"               ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)\r
+        BuildDir = os.path.join(\r
+            GenFdsGlobalVariable.OutputDirDict[Arch],\r
+            Arch,\r
+            PathClassObj.SubDir,\r
+            PathClassObj.BaseName\r
+        )\r
+        Macro["MODULE_BUILD_DIR"      ] = BuildDir\r
+        Macro["OUTPUT_DIR"            ] = os.path.join(BuildDir, "OUTPUT")\r
+        Macro["DEBUG_DIR"             ] = os.path.join(BuildDir, "DEBUG")\r
+\r
+        BuildRules = {}\r
+        for Type in BuildRuleDatabase.FileTypeList:\r
+            #first try getting build rule by BuildRuleFamily\r
+            RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]\r
+            if not RuleObject:\r
+                # build type is always module type, but ...\r
+                if Inf.ModuleType != Inf.BuildType:\r
+                    RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily]\r
+            #second try getting build rule by ToolChainFamily\r
+            if not RuleObject:\r
+                RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]\r
+                if not RuleObject:\r
+                    # build type is always module type, but ...\r
+                    if Inf.ModuleType != Inf.BuildType:\r
+                        RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]\r
+            if not RuleObject:\r
+                continue\r
+            RuleObject = RuleObject.Instantiate(Macro)\r
+            BuildRules[Type] = RuleObject\r
+            for Ext in RuleObject.SourceFileExtList:\r
+                BuildRules[Ext] = RuleObject\r
+        return BuildRules\r
+\r
+    ## GetModuleCodaTargetList\r
+    #\r
+    #    @param Inf: object of InfBuildData\r
+    #    @param Arch: current arch\r
+    #\r
+    @staticmethod\r
+    def GetModuleCodaTargetList(Inf, Arch):\r
+        BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)\r
+        if not BuildRules:\r
+            return []\r
+\r
+        TargetList = set()\r
+        FileList = []\r
+\r
+        if not Inf.IsBinaryModule:\r
+            for File in Inf.Sources:\r
+                if File.TagName in ("", "*", GenFdsGlobalVariable.ToolChainTag) and \\r
+                    File.ToolChainFamily in ("", "*", GenFdsGlobalVariable.ToolChainFamily):\r
+                    FileList.append((File, DataType.TAB_UNKNOWN_FILE))\r
+\r
+        for File in Inf.Binaries:\r
+            if File.Target in [DataType.TAB_COMMON, '*', GenFdsGlobalVariable.TargetName]:\r
+                FileList.append((File, File.Type))\r
+\r
+        for File, FileType in FileList:\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 File.IsBinary and File == Source and Inf.Binaries is not None and File in Inf.Binaries:\r
+                    # Skip all files that are not binary libraries\r
+                    if not Inf.LibraryClass:\r
+                        continue            \r
+                    RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE]\r
+                elif FileType in BuildRules:\r
+                    RuleObject = BuildRules[FileType]\r
+                elif Source.Ext in BuildRules:\r
+                    RuleObject = BuildRules[Source.Ext]\r
+                else:\r
+                    # stop at no more rules\r
+                    if LastTarget:\r
+                        TargetList.add(str(LastTarget))\r
+                    break\r
+    \r
+                FileType = RuleObject.SourceFileType\r
+    \r
+                # stop at STATIC_LIBRARY for library\r
+                if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:\r
+                    if LastTarget:\r
+                        TargetList.add(str(LastTarget))\r
+                    break\r
+    \r
+                Target = RuleObject.Apply(Source)\r
+                if not Target:\r
+                    if LastTarget:\r
+                        TargetList.add(str(LastTarget))\r
+                    break\r
+                elif not Target.Outputs:\r
+                    # Only do build for target with outputs\r
+                    TargetList.add(str(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 = DataType.TAB_UNKNOWN_FILE\r
+                for Cmd in Target.Commands:\r
+                    if "$(CP)" == Cmd.split()[0]:\r
+                        CpTarget = Cmd.split()[2]\r
+                        TargetList.add(CpTarget)\r
+\r
+        return list(TargetList)\r
+\r
+    ## SetDir()\r
+    #\r
+    #   @param  OutputDir           Output directory\r
+    #   @param  FdfParser           FDF contents parser\r
+    #   @param  Workspace           The directory of workspace\r
+    #   @param  ArchList            The Arch list of platform\r
+    #\r
+    def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):\r
+        GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir :%s" % OutputDir)\r
+#        GenFdsGlobalVariable.OutputDirDict = OutputDir\r
+        GenFdsGlobalVariable.FdfParser = FdfParser\r
+        GenFdsGlobalVariable.WorkSpace = WorkSpace\r
+        GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)\r
+        if not os.path.exists(GenFdsGlobalVariable.FvDir) :\r
+            os.makedirs(GenFdsGlobalVariable.FvDir)\r
+        GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
+        if not os.path.exists(GenFdsGlobalVariable.FfsDir) :\r
+            os.makedirs(GenFdsGlobalVariable.FfsDir)\r
+\r
+        T_CHAR_LF = '\n'\r
+        #\r
+        # Create FV Address inf file\r
+        #\r
+        GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')\r
+        FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')\r
+        #\r
+        # Add [Options]\r
+        #\r
+        FvAddressFile.writelines("[options]" + T_CHAR_LF)\r
+        BsAddress = '0'\r
+        for Arch in ArchList:\r
+            if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:\r
+                BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress\r
+                break\r
+\r
+        FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r
+                                       BsAddress + \\r
+                                       T_CHAR_LF)\r
+\r
+        RtAddress = '0'\r
+        for Arch in ArchList:\r
+            if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress:\r
+                RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress\r
+\r
+        FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r
+                                       RtAddress + \\r
+                                       T_CHAR_LF)\r
+\r
+        FvAddressFile.close()\r
+\r
+    def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData):\r
+        GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile\r
+        GenFdsGlobalVariable.FdfParser = FdfParser\r
+        GenFdsGlobalVariable.WorkSpace = WorkSpace.Db\r
+        GenFdsGlobalVariable.ArchList = ArchList\r
+        GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]\r
+        GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"]\r
+        GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform\r
+        GenFdsGlobalVariable.EdkSourceDir = GlobalData.gGlobalDefines["EDK_SOURCE"]\r
+        GenFdsGlobalVariable.ConfDir  = GlobalData.gConfDirectory\r
+        GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread\r
+        for Arch in ArchList:\r
+            GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath(\r
+                os.path.join(GlobalData.gWorkspace,\r
+                             WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,GlobalData.gGlobalDefines['TARGET'],\r
+                             GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory,\r
+                             GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN']))\r
+            GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath(\r
+                             WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
+                             GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory)\r
+            GenFdsGlobalVariable.PlatformName = WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
+                                                                      GlobalData.gGlobalDefines['TARGET'],\r
+                                                                      GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName\r
+        GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)\r
+        if not os.path.exists(GenFdsGlobalVariable.FvDir):\r
+            os.makedirs(GenFdsGlobalVariable.FvDir)\r
+        GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
+        if not os.path.exists(GenFdsGlobalVariable.FfsDir):\r
+            os.makedirs(GenFdsGlobalVariable.FfsDir)\r
+\r
+        T_CHAR_LF = '\n'\r
+        #\r
+        # Create FV Address inf file\r
+        #\r
+        GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')\r
+        FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')\r
+        #\r
+        # Add [Options]\r
+        #\r
+        FvAddressFile.writelines("[options]" + T_CHAR_LF)\r
+        BsAddress = '0'\r
+        for Arch in ArchList:\r
+            BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,\r
+                                                                   GlobalData.gGlobalDefines['TARGET'],\r
+                                                                   GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress\r
+            if BsAddress:\r
+                break\r
+\r
+        FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r
+                                 BsAddress + \\r
+                                 T_CHAR_LF)\r
+\r
+        RtAddress = '0'\r
+        for Arch in ArchList:\r
+            if GenFdsGlobalVariable.WorkSpace.BuildObject[\r
+                GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],\r
+                GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress:\r
+                RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[\r
+                    GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],\r
+                    GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress\r
+\r
+        FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r
+                                 RtAddress + \\r
+                                 T_CHAR_LF)\r
+\r
+        FvAddressFile.close()\r
+\r
+    ## ReplaceWorkspaceMacro()\r
+    #\r
+    #   @param  String           String that may contain macro\r
+    #\r
+    def ReplaceWorkspaceMacro(String):\r
+        String = mws.handleWsMacro(String)\r
+        Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)\r
+        if os.path.exists(Str):\r
+            if not os.path.isabs(Str):\r
+                Str = os.path.abspath(Str)\r
+        else:\r
+            Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String)\r
+        return os.path.normpath(Str)\r
+\r
+    ## Check if the input files are newer than output files\r
+    #\r
+    #   @param  Output          Path of output file\r
+    #   @param  Input           Path list of input files\r
+    #\r
+    #   @retval True            if Output doesn't exist, or any Input is newer\r
+    #   @retval False           if all Input is older than Output\r
+    #\r
+    @staticmethod\r
+    def NeedsUpdate(Output, Input):\r
+        if not os.path.exists(Output):\r
+            return True\r
+        # always update "Output" if no "Input" given\r
+        if Input is None or len(Input) == 0:\r
+            return True\r
+\r
+        # if fdf file is changed after the 'Output" is generated, update the 'Output'\r
+        OutputTime = os.path.getmtime(Output)\r
+        if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:\r
+            return True\r
+\r
+        for F in Input:\r
+            # always update "Output" if any "Input" doesn't exist\r
+            if not os.path.exists(F):\r
+                return True\r
+            # always update "Output" if any "Input" is newer than "Output"\r
+            if os.path.getmtime(F) > OutputTime:\r
+                return True\r
+        return False\r
+\r
+    @staticmethod\r
+    def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,\r
+                        GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=[], BuildNumber=None, DummyFile=None, IsMakefile=False):\r
+        Cmd = ["GenSec"]\r
+        if Type:\r
+            Cmd += ("-s", Type)\r
+        if CompressionType:\r
+            Cmd += ("-c", CompressionType)\r
+        if Guid is not None:\r
+            Cmd += ("-g", Guid)\r
+        if DummyFile is not None:\r
+            Cmd += ("--dummy", DummyFile)\r
+        if GuidHdrLen:\r
+            Cmd += ("-l", GuidHdrLen)\r
+        #Add each guided attribute\r
+        for Attr in GuidAttr:\r
+            Cmd += ("-r", Attr)\r
+        #Section Align is only for dummy section without section type\r
+        for SecAlign in InputAlign:\r
+            Cmd += ("--sectionalign", SecAlign)\r
+\r
+        CommandFile = Output + '.txt'\r
+        if Ui:\r
+            if IsMakefile:\r
+                if Ui == "$(MODULE_NAME)":\r
+                    Cmd += ('-n', Ui)\r
+                else:\r
+                    Cmd += ("-n", '"' + Ui + '"')\r
+                Cmd += ("-o", Output)\r
+                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
+                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
+            else:\r
+                SectionData = array.array('B', [0, 0, 0, 0])\r
+                SectionData.fromstring(Ui.encode("utf_16_le"))\r
+                SectionData.append(0)\r
+                SectionData.append(0)\r
+                Len = len(SectionData)\r
+                GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)\r
+                SaveFileOnChange(Output, SectionData.tostring())\r
+\r
+        elif Ver:\r
+            Cmd += ("-n", Ver)\r
+            if BuildNumber:\r
+                Cmd += ("-j", BuildNumber)\r
+            Cmd += ("-o", Output)\r
+\r
+            SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
+            if IsMakefile:\r
+                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
+                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
+            else:\r
+                if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r
+                    return\r
+                GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r
+        else:\r
+            Cmd += ("-o", Output)\r
+            Cmd += Input\r
+\r
+            SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
+            if IsMakefile:\r
+                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
+                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())\r
+            elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r
+                GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
+                GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r
+                if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and\r
+                    GenFdsGlobalVariable.LargeFileInFvFlags):\r
+                    GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True\r
+\r
+    @staticmethod\r
+    def GetAlignment (AlignString):\r
+        if AlignString is None:\r
+            return 0\r
+        if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K"):\r
             return int (AlignString.rstrip('K')) * 1024\r
+        elif AlignString in ("1M", "2M", "4M", "8M", "16M"):\r
+            return int (AlignString.rstrip('M')) * 1024 * 1024\r
         else:\r
             return int (AlignString)\r
-
-    @staticmethod
-    def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
-                    SectionAlign=None):
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
-            return
-        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
-
-        Cmd = ["GenFfs", "-t", Type, "-g", Guid]
-        if Fixed == True:
-            Cmd += ["-x"]
-        if CheckSum:
-            Cmd += ["-s"]
-        if Align not in [None, '']:
-            Cmd += ["-a", Align]
-
-        Cmd += ["-o", Output]
-        for I in range(0, len(Input)):
-            Cmd += ("-i", Input[I])
-            if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']:
-                Cmd += ("-n", SectionAlign[I])
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")
-
-    @staticmethod
-    def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,
-                               AddressFile=None, MapFile=None, FfsList=[]):
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):
-            return
-        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
-
-        Cmd = ["GenFv"]
-        if BaseAddress not in [None, '']:
-            Cmd += ["-r", BaseAddress]
-        
-        if ForceRebase == False:
-            Cmd +=["-F", "FALSE"]
-        elif ForceRebase == True:
-            Cmd +=["-F", "TRUE"]
-                        
-        if Capsule:
-            Cmd += ["-c"]
-        if Dump:
-            Cmd += ["-p"]
-        if AddressFile not in [None, '']:
-            Cmd += ["-a", AddressFile]
-        if MapFile not in [None, '']:
-            Cmd += ["-m", MapFile]
-        Cmd += ["-o", Output]
-        for I in Input:
-            Cmd += ["-i", I]
-
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")
-
-    @staticmethod
-    def GenerateVtf(Output, Input, BaseAddress=None, FvSize=None):
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
-            return
-        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
-
-        Cmd = ["GenVtf"]
-        if BaseAddress not in [None, ''] and FvSize not in [None, ''] \
-            and len(BaseAddress) == len(FvSize):
-            for I in range(0, len(BaseAddress)):
-                Cmd += ["-r", BaseAddress[I], "-s", FvSize[I]]
-        Cmd += ["-o", Output]
-        for F in Input:
-            Cmd += ["-f", F]
-
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF")
-
-    @staticmethod
-    def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,
-                              Strip=False, Replace=False, TimeStamp=None, Join=False,
-                              Align=None, Padding=None, Convert=False):
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
-            return
-        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
-
-        Cmd = ["GenFw"]
-        if Type.lower() == "te":
-            Cmd += ["-t"]
-        if SubType not in [None, '']:
-            Cmd += ["-e", SubType]
-        if TimeStamp not in [None, '']:
-            Cmd += ["-s", TimeStamp]
-        if Align not in [None, '']:
-            Cmd += ["-a", Align]
-        if Padding not in [None, '']:
-            Cmd += ["-p", Padding]
-        if Zero:
-            Cmd += ["-z"]
-        if Strip:
-            Cmd += ["-l"]
-        if Replace:
-            Cmd += ["-r"]
-        if Join:
-            Cmd += ["-j"]
-        if Convert:
-            Cmd += ["-m"]
-        Cmd += ["-o", Output]
-        Cmd += Input
-
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")
-
-    @staticmethod
-    def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,
-                        Revision=None, DeviceId=None, VendorId=None):
-        InputList = []   
-        Cmd = ["EfiRom"]
-        if len(EfiInput) > 0:
-            
-            if Compress:
-                Cmd += ["-ec"]
-            else:
-                Cmd += ["-e"]
-                
-            for EfiFile in EfiInput:
-                Cmd += [EfiFile]
-                InputList.append (EfiFile)
-        
-        if len(BinaryInput) > 0:
-            Cmd += ["-b"]
-            for BinFile in BinaryInput:
-                Cmd += [BinFile]
-                InputList.append (BinFile)
-
-        # Check List
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList):
-            return
-        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))
-                        
-        if ClassCode != None:
-            Cmd += ["-l", ClassCode]
-        if Revision != None:
-            Cmd += ["-r", Revision]
-        if DeviceId != None:
-            Cmd += ["-i", DeviceId]
-        if VendorId != None:
-            Cmd += ["-f", VendorId]
-
-        Cmd += ["-o", Output]    
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")
-
-    @staticmethod
-    def GuidTool(Output, Input, ToolPath, Options='', returnValue=[]):
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
-            return
-        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
-
-        Cmd = [ToolPath, ]
-        Cmd += Options.split(' ')
-        Cmd += ["-o", Output]
-        Cmd += Input
-
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)
-
-    def CallExternalTool (cmd, errorMess, returnValue=[]):
-
-        if type(cmd) not in (tuple, list):
-            GenFdsGlobalVariable.ErrorLogger("ToolError!  Invalid parameter type in call to CallExternalTool")
-
-        if GenFdsGlobalVariable.DebugLevel != -1:
-            cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))
-            GenFdsGlobalVariable.InfLogger (cmd)
-
-        if GenFdsGlobalVariable.VerboseMode:
-            cmd += ('-v',)
-            GenFdsGlobalVariable.InfLogger (cmd)
-        else:
-            sys.stdout.write ('#')
-            sys.stdout.flush()
-            GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1
-            if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:
-                sys.stdout.write('\n')
-
-        try:
-            PopenObject = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr= subprocess.PIPE)
-        except Exception, X:
-            EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))
-        (out, error) = PopenObject.communicate()
-
-        while PopenObject.returncode == None :
-            PopenObject.wait()
-        if returnValue != [] and returnValue[0] != 0:
-            #get command return value
-            returnValue[0] = PopenObject.returncode
-            return
-        if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:
-            GenFdsGlobalVariable.InfLogger ("Return Value = %d" %PopenObject.returncode)
-            GenFdsGlobalVariable.InfLogger (out)
-            GenFdsGlobalVariable.InfLogger (error)
-            if PopenObject.returncode != 0:
-                print "###", cmd
-                EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)
-
-    def VerboseLogger (msg):
-        EdkLogger.verbose(msg)
-
-    def InfLogger (msg):
-        EdkLogger.info(msg)
-
-    def ErrorLogger (msg, File = None, Line = None, ExtraData = None):
-        EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)
-
-    def DebugLogger (Level, msg):
-        EdkLogger.debug(Level, msg)
-
-    ## ReplaceWorkspaceMacro()
-    #
-    #   @param  Str           String that may contain macro
-    #   @param  MacroDict     Dictionary that contains macro value pair
-    #
-    def MacroExtend (Str, MacroDict = {}, Arch = 'COMMON'):
-        if Str == None :
-            return None
-
-        Dict = {'$(WORKSPACE)'   : GenFdsGlobalVariable.WorkSpaceDir,
-                '$(EDK_SOURCE)'  : GenFdsGlobalVariable.EdkSourceDir,
-#                '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
-                '$(TARGET)' : GenFdsGlobalVariable.TargetName,
-                '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag
-               }
-        OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]
-        if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList:
-            OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]
-
-        Dict['$(OUTPUT_DIRECTORY)'] = OutputDir
-
-        if MacroDict != None  and len (MacroDict) != 0:
-            Dict.update(MacroDict)
-
-        for key in Dict.keys():
-            if Str.find(key) >= 0 :
-                Str = Str.replace (key, Dict[key])
-
-        if Str.find('$(ARCH)') >= 0:
-            if len(GenFdsGlobalVariable.ArchList) == 1:
-                Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])
-            else:
-                EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)
-
-        return Str
-
-    ## GetPcdValue()
-    #
-    #   @param  PcdPattern           pattern that labels a PCD.
-    #
-    def GetPcdValue (PcdPattern):
-        if PcdPattern == None :
-            return None
-        PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.')
-        TokenSpace = PcdPair[0]
-        TokenCName = PcdPair[1]
-
-        PcdValue = ''
-        for Platform in GenFdsGlobalVariable.WorkSpace.PlatformList:
-            #
-            # Only process platform which match current build option.
-            #
-            if Platform.MetaFile == GenFdsGlobalVariable.ActivePlatform:            
-                PcdDict = Platform.Pcds
-                for Key in PcdDict:
-                    PcdObj = PcdDict[Key]
-                    if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
-                        if PcdObj.Type != 'FixedAtBuild':
-                            EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
-                        if PcdObj.DatumType != 'VOID*':
-                            EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
-                            
-                        PcdValue = PcdObj.DefaultValue
-                        return PcdValue
-
-        for Package in GenFdsGlobalVariable.WorkSpace.PackageList:
-            PcdDict = Package.Pcds
-            for Key in PcdDict:
-                PcdObj = PcdDict[Key]
-                if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
-                    if PcdObj.Type != 'FixedAtBuild':
-                        EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
-                    if PcdObj.DatumType != 'VOID*':
-                        EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
-                        
-                    PcdValue = PcdObj.DefaultValue
-                    return PcdValue
-
-        return PcdValue
-
-    SetDir = staticmethod(SetDir)
-    ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro)
-    CallExternalTool = staticmethod(CallExternalTool)
-    VerboseLogger = staticmethod(VerboseLogger)
-    InfLogger = staticmethod(InfLogger)
-    ErrorLogger = staticmethod(ErrorLogger)
-    DebugLogger = staticmethod(DebugLogger)
-    MacroExtend = staticmethod (MacroExtend)
-    GetPcdValue = staticmethod(GetPcdValue)
+\r
+    @staticmethod\r
+    def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,\r
+                    SectionAlign=None, MakefilePath=None):\r
+        Cmd = ["GenFfs", "-t", Type, "-g", Guid]\r
+        mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]\r
+        if Fixed == True:\r
+            Cmd.append("-x")\r
+        if CheckSum:\r
+            Cmd.append("-s")\r
+        if Align:\r
+            if Align not in mFfsValidAlign:\r
+                Align = GenFdsGlobalVariable.GetAlignment (Align)\r
+                for index in range(0, len(mFfsValidAlign) - 1):\r
+                    if ((Align > GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index])) and (Align <= GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index + 1]))):\r
+                        break\r
+                Align = mFfsValidAlign[index + 1]\r
+            Cmd += ("-a", Align)\r
+\r
+        Cmd += ("-o", Output)\r
+        for I in range(0, len(Input)):\r
+            Cmd += ("-i", Input[I])\r
+            if SectionAlign and SectionAlign[I]:\r
+                Cmd += ("-n", SectionAlign[I])\r
+\r
+        CommandFile = Output + '.txt'\r
+        SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r
+\r
+        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
+        if MakefilePath:\r
+            if (tuple(Cmd),tuple(GenFdsGlobalVariable.SecCmdList),tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict:\r
+                GenFdsGlobalVariable.FfsCmdDict[tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)] = MakefilePath\r
+            GenFdsGlobalVariable.SecCmdList = []\r
+            GenFdsGlobalVariable.CopyList = []\r
+        else:\r
+            if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r
+                return\r
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")\r
+\r
+    @staticmethod\r
+    def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,\r
+                               AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None):\r
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):\r
+            return\r
+        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
+\r
+        Cmd = ["GenFv"]\r
+        if BaseAddress:\r
+            Cmd += ("-r", BaseAddress)\r
+\r
+        if ForceRebase == False:\r
+            Cmd += ("-F", "FALSE")\r
+        elif ForceRebase == True:\r
+            Cmd += ("-F", "TRUE")\r
+\r
+        if Capsule:\r
+            Cmd.append("-c")\r
+        if Dump:\r
+            Cmd.append("-p")\r
+        if AddressFile:\r
+            Cmd += ("-a", AddressFile)\r
+        if MapFile:\r
+            Cmd += ("-m", MapFile)\r
+        if FileSystemGuid:\r
+            Cmd += ("-g", FileSystemGuid)\r
+        Cmd += ("-o", Output)\r
+        for I in Input:\r
+            Cmd += ("-i", I)\r
+\r
+        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")\r
+\r
+    @staticmethod\r
+    def GenerateVtf(Output, Input, BaseAddress=None, FvSize=None):\r
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):\r
+            return\r
+        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
+\r
+        Cmd = ["GenVtf"]\r
+        if BaseAddress and FvSize \\r
+            and len(BaseAddress) == len(FvSize):\r
+            for I in range(0, len(BaseAddress)):\r
+                Cmd += ("-r", BaseAddress[I], "-s", FvSize[I])\r
+        Cmd += ("-o", Output)\r
+        for F in Input:\r
+            Cmd += ("-f", F)\r
+\r
+        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF")\r
+\r
+    @staticmethod\r
+    def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,\r
+                              Strip=False, Replace=False, TimeStamp=None, Join=False,\r
+                              Align=None, Padding=None, Convert=False, IsMakefile=False):\r
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:\r
+            return\r
+        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
+\r
+        Cmd = ["GenFw"]\r
+        if Type.lower() == "te":\r
+            Cmd.append("-t")\r
+        if SubType:\r
+            Cmd += ("-e", SubType)\r
+        if TimeStamp:\r
+            Cmd += ("-s", TimeStamp)\r
+        if Align:\r
+            Cmd += ("-a", Align)\r
+        if Padding:\r
+            Cmd += ("-p", Padding)\r
+        if Zero:\r
+            Cmd.append("-z")\r
+        if Strip:\r
+            Cmd.append("-l")\r
+        if Replace:\r
+            Cmd.append("-r")\r
+        if Join:\r
+            Cmd.append("-j")\r
+        if Convert:\r
+            Cmd.append("-m")\r
+        Cmd += ("-o", Output)\r
+        Cmd += Input\r
+        if IsMakefile:\r
+            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
+                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())\r
+        else:\r
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")\r
+\r
+    @staticmethod\r
+    def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,\r
+                        Revision=None, DeviceId=None, VendorId=None, IsMakefile=False):\r
+        InputList = []   \r
+        Cmd = ["EfiRom"]\r
+        if len(EfiInput) > 0:\r
+            \r
+            if Compress:\r
+                Cmd.append("-ec")\r
+            else:\r
+                Cmd.append("-e")\r
+                \r
+            for EfiFile in EfiInput:\r
+                Cmd.append(EfiFile)\r
+                InputList.append (EfiFile)\r
+        \r
+        if len(BinaryInput) > 0:\r
+            Cmd.append("-b")\r
+            for BinFile in BinaryInput:\r
+                Cmd.append(BinFile)\r
+                InputList.append (BinFile)\r
+\r
+        # Check List\r
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList) and not IsMakefile:\r
+            return\r
+        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))\r
+                        \r
+        if ClassCode is not None:\r
+            Cmd += ("-l", ClassCode)\r
+        if Revision is not None:\r
+            Cmd += ("-r", Revision)\r
+        if DeviceId is not None:\r
+            Cmd += ("-i", DeviceId)\r
+        if VendorId is not None:\r
+            Cmd += ("-f", VendorId)\r
+\r
+        Cmd += ("-o", Output)\r
+        if IsMakefile:\r
+            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
+                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())\r
+        else:\r
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")\r
+\r
+    @staticmethod\r
+    def GuidTool(Output, Input, ToolPath, Options='', returnValue=[], IsMakefile=False):\r
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:\r
+            return\r
+        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r
+\r
+        Cmd = [ToolPath, ]\r
+        Cmd += Options.split(' ')\r
+        Cmd += ("-o", Output)\r
+        Cmd += Input\r
+        if IsMakefile:\r
+            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:\r
+                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())\r
+        else:\r
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)\r
+\r
+    def CallExternalTool (cmd, errorMess, returnValue=[]):\r
+\r
+        if type(cmd) not in (tuple, list):\r
+            GenFdsGlobalVariable.ErrorLogger("ToolError!  Invalid parameter type in call to CallExternalTool")\r
+\r
+        if GenFdsGlobalVariable.DebugLevel != -1:\r
+            cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))\r
+            GenFdsGlobalVariable.InfLogger (cmd)\r
+\r
+        if GenFdsGlobalVariable.VerboseMode:\r
+            cmd += ('-v',)\r
+            GenFdsGlobalVariable.InfLogger (cmd)\r
+        else:\r
+            sys.stdout.write ('#')\r
+            sys.stdout.flush()\r
+            GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1\r
+            if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:\r
+                sys.stdout.write('\n')\r
+\r
+        try:\r
+            PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
+        except Exception, X:\r
+            EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))\r
+        (out, error) = PopenObject.communicate()\r
+\r
+        while PopenObject.returncode is None :\r
+            PopenObject.wait()\r
+        if returnValue != [] and returnValue[0] != 0:\r
+            #get command return value\r
+            returnValue[0] = PopenObject.returncode\r
+            return\r
+        if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:\r
+            GenFdsGlobalVariable.InfLogger ("Return Value = %d" % PopenObject.returncode)\r
+            GenFdsGlobalVariable.InfLogger (out)\r
+            GenFdsGlobalVariable.InfLogger (error)\r
+            if PopenObject.returncode != 0:\r
+                print "###", cmd\r
+                EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)\r
+\r
+    def VerboseLogger (msg):\r
+        EdkLogger.verbose(msg)\r
+\r
+    def InfLogger (msg):\r
+        EdkLogger.info(msg)\r
+\r
+    def ErrorLogger (msg, File=None, Line=None, ExtraData=None):\r
+        EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)\r
+\r
+    def DebugLogger (Level, msg):\r
+        EdkLogger.debug(Level, msg)\r
+\r
+    ## ReplaceWorkspaceMacro()\r
+    #\r
+    #   @param  Str           String that may contain macro\r
+    #   @param  MacroDict     Dictionary that contains macro value pair\r
+    #\r
+    def MacroExtend (Str, MacroDict={}, Arch=DataType.TAB_COMMON):\r
+        if Str is None :\r
+            return None\r
+\r
+        Dict = {'$(WORKSPACE)'   : GenFdsGlobalVariable.WorkSpaceDir,\r
+                '$(EDK_SOURCE)'  : GenFdsGlobalVariable.EdkSourceDir,\r
+#                '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,\r
+                '$(TARGET)' : GenFdsGlobalVariable.TargetName,\r
+                '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag,\r
+                '$(SPACE)' : ' '\r
+               }\r
+        OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]\r
+        if Arch != DataType.TAB_COMMON and Arch in GenFdsGlobalVariable.ArchList:\r
+            OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]\r
+\r
+        Dict['$(OUTPUT_DIRECTORY)'] = OutputDir\r
+\r
+        if MacroDict is not None  and len (MacroDict) != 0:\r
+            Dict.update(MacroDict)\r
+\r
+        for key in Dict:\r
+            if Str.find(key) >= 0 :\r
+                Str = Str.replace (key, Dict[key])\r
+\r
+        if Str.find('$(ARCH)') >= 0:\r
+            if len(GenFdsGlobalVariable.ArchList) == 1:\r
+                Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])\r
+            else:\r
+                EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)\r
+\r
+        return Str\r
+\r
+    ## GetPcdValue()\r
+    #\r
+    #   @param  PcdPattern           pattern that labels a PCD.\r
+    #\r
+    def GetPcdValue (PcdPattern):\r
+        if PcdPattern is None :\r
+            return None\r
+        PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.')\r
+        TokenSpace = PcdPair[0]\r
+        TokenCName = PcdPair[1]\r
+\r
+        PcdValue = ''\r
+        for Arch in GenFdsGlobalVariable.ArchList:\r
+            Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
+            PcdDict = Platform.Pcds\r
+            for Key in PcdDict:\r
+                PcdObj = PcdDict[Key]\r
+                if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):\r
+                    if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD:\r
+                        EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)\r
+                    if PcdObj.DatumType != DataType.TAB_VOID:\r
+                        EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r
+                        \r
+                    PcdValue = PcdObj.DefaultValue\r
+                    return PcdValue\r
+\r
+            for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,\r
+                                                                         Arch,\r
+                                                                         GenFdsGlobalVariable.TargetName,\r
+                                                                         GenFdsGlobalVariable.ToolChainTag):\r
+                PcdDict = Package.Pcds\r
+                for Key in PcdDict:\r
+                    PcdObj = PcdDict[Key]\r
+                    if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):\r
+                        if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD:\r
+                            EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)\r
+                        if PcdObj.DatumType != DataType.TAB_VOID:\r
+                            EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r
+                            \r
+                        PcdValue = PcdObj.DefaultValue\r
+                        return PcdValue\r
+\r
+        return PcdValue\r
+\r
+    SetDir = staticmethod(SetDir)\r
+    SetEnv = staticmethod(SetEnv)\r
+    ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro)\r
+    CallExternalTool = staticmethod(CallExternalTool)\r
+    VerboseLogger = staticmethod(VerboseLogger)\r
+    InfLogger = staticmethod(InfLogger)\r
+    ErrorLogger = staticmethod(ErrorLogger)\r
+    DebugLogger = staticmethod(DebugLogger)\r
+    MacroExtend = staticmethod (MacroExtend)\r
+    GetPcdValue = staticmethod(GetPcdValue)\r