Added FDF file in dependency check
authorjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Wed, 11 Jun 2008 05:30:28 +0000 (05:30 +0000)
committerjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Wed, 11 Jun 2008 05:30:28 +0000 (05:30 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1252 7335b38e-4728-0410-8992-fb3ffe349368

Source/Python/GenFds/GenFds.py
Source/Python/GenFds/GenFdsGlobalVariable.py

index c2473fd..b9a7074 100644 (file)
-## @file\r
-# generate flash image\r
-#\r
-#  Copyright (c) 2007, 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
-from optparse import OptionParser\r
-import sys\r
-import os\r
-import FdfParser\r
-from Common import BuildToolError\r
-from GenFdsGlobalVariable import GenFdsGlobalVariable\r
-from Workspace.WorkspaceDatabase import WorkspaceDatabase\r
-import RuleComplexFile\r
-from EfiSection import EfiSection\r
-import StringIO\r
-import Common.TargetTxtClassObject as TargetTxtClassObject\r
-import Common.DataType\r
-import Common.GlobalData as GlobalData\r
-from Common import EdkLogger\r
-from Common.String import *\r
-\r
-## Version and Copyright\r
-versionNumber = "1.0"\r
-__version__ = "%prog Version " + versionNumber\r
-__copyright__ = "Copyright (c) 2007, Intel Corporation  All rights reserved."\r
-\r
-## Tool entrance method\r
-#\r
-# This method mainly dispatch specific methods per the command line options.\r
-# If no error found, return zero value so the caller of this tool can know\r
-# if it's executed successfully or not.\r
-#\r
-#   @retval 0     Tool was successful\r
-#   @retval 1     Tool failed\r
-#\r
-def main():\r
-    global Options\r
-    Options = myOptionParser()\r
-    global Workspace\r
-    Workspace = ""\r
-    ArchList = None\r
-    ReturnCode = 0\r
-\r
-    EdkLogger.Initialize()\r
-    try:\r
-        if Options.verbose != None:\r
-            EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
-            GenFdsGlobalVariable.VerboseMode = True\r
-        if Options.quiet != None:\r
-            EdkLogger.SetLevel(EdkLogger.QUIET)\r
-        if Options.debug != None:\r
-            EdkLogger.SetLevel(Options.debug + 1)\r
-            GenFdsGlobalVariable.DebugLevel = Options.debug\r
-        else:\r
-            EdkLogger.SetLevel(EdkLogger.INFO)\r
-\r
-        if (Options.Workspace == None):\r
-            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "WORKSPACE not defined",\r
-                            ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
-        else:\r
-            Workspace = Options.Workspace\r
-            GenFdsGlobalVariable.WorkSpaceDir = Workspace\r
-            if 'EDK_SOURCE' in os.environ.keys():\r
-                GenFdsGlobalVariable.EdkSourceDir = os.environ['EDK_SOURCE']\r
-            if (Options.debug):\r
-                GenFdsGlobalVariable.VerboseLogger( "Using Workspace:" + Workspace)\r
-        os.chdir(GenFdsGlobalVariable.WorkSpaceDir)\r
-\r
-        if (Options.filename):\r
-            FdfFilename = Options.filename\r
-            FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)\r
-        else:\r
-            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing FDF filename")\r
-\r
-        if (Options.BuildTarget):\r
-            GenFdsGlobalVariable.TargetName = Options.BuildTarget\r
-        else:\r
-            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing build target")\r
-\r
-        if (Options.ToolChain):\r
-            GenFdsGlobalVariable.ToolChainTag = Options.ToolChain\r
-        else:\r
-            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing tool chain tag")\r
-\r
-        if FdfFilename[0:2] == '..':\r
-            FdfFilename = os.path.realpath(FdfFilename)\r
-        if FdfFilename[1] != ':':\r
-            FdfFilename = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)\r
-\r
-        if not os.path.exists(FdfFilename):\r
-            EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=FdfFilename)\r
-\r
-        if (Options.activePlatform):\r
-            ActivePlatform = Options.activePlatform\r
-            ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform)\r
-\r
-            if ActivePlatform[0:2] == '..':\r
-                ActivePlatform = os.path.realpath(ActivePlatform)\r
-\r
-            if ActivePlatform[1] != ':':\r
-                ActivePlatform = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)\r
-\r
-            if not os.path.exists(ActivePlatform)  :\r
-                EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist!")\r
-\r
-            if ActivePlatform.find(Workspace) == -1:\r
-                EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist in Workspace!")\r
-\r
-            ActivePlatform = ActivePlatform.replace(Workspace, '')\r
-            if len(ActivePlatform) > 0 :\r
-                if ActivePlatform[0] == '\\' or ActivePlatform[0] == '/':\r
-                    ActivePlatform = ActivePlatform[1:]\r
-            else:\r
-                EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist!")\r
-        else :\r
-            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing active platform")\r
-\r
-        GenFdsGlobalVariable.ActivePlatform = NormPath(ActivePlatform)\r
-\r
-        if (Options.archList) :\r
-            ArchList = Options.archList.split(',')\r
-        else:\r
-            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing build ARCH")\r
-\r
-        BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, "Conf/target.txt"))\r
-        if os.path.isfile(BuildConfigurationFile) == True:\r
-            TargetTxtClassObject.TargetTxtClassObject(BuildConfigurationFile)\r
-        else:\r
-            EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=BuildConfigrationFile)\r
-\r
-        if Options.Macros:\r
-            for Pair in Options.Macros:\r
-                Pair.strip('"')\r
-                List = Pair.split('=')\r
-                if len(List) == 2:\r
-                    FdfParser.InputMacroDict[List[0].strip()] = List[1].strip()\r
-                    GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip()\r
-                else:\r
-                    FdfParser.InputMacroDict[List[0].strip()] = None\r
-\r
-        """call Workspace build create database"""\r
-        os.environ["WORKSPACE"] = Workspace\r
-        BuildWorkSpace = WorkspaceDatabase(':memory:', GlobalData.gGlobalDefines)\r
-        BuildWorkSpace.InitDatabase()\r
-\r
-        for Arch in ArchList:\r
-            GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[ActivePlatform, Arch].OutputDirectory)\r
-\r
-        if (Options.outputDir):\r
-            OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir)\r
-            for Arch in ArchList:\r
-                GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine\r
-        else:\r
-            for Arch in ArchList:\r
-                GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)\r
-\r
-        for Key in GenFdsGlobalVariable.OutputDirDict:\r
-            OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]\r
-            if OutputDir[0:2] == '..':\r
-                OutputDir = os.path.realpath(OutputDir)\r
-\r
-            if OutputDir[1] != ':':\r
-                OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)\r
-\r
-            if not os.path.exists(OutputDir):\r
-                EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=OutputDir)\r
-            GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir\r
-\r
-        """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """\r
-        FdfParserObj = FdfParser.FdfParser(FdfFilename)\r
-        FdfParserObj.ParseFile()\r
-\r
-        if FdfParserObj.CycleReferenceCheck():\r
-            EdkLogger.error("GenFds", BuildToolError.FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")\r
-\r
-        if (Options.uiFdName) :\r
-            if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys():\r
-                GenFds.currentFd = Options.uiFdName\r
-            else:\r
-                EdkLogger.error("GenFds", BuildToolError.OPTION_VALUE_INVALID,\r
-                                "No such an FD in FDF file: %s" % Options.uiFdName)\r
-\r
-        if (Options.uiFvName) :\r
-            if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys():\r
-                GenFds.currentFv = Options.uiFvName\r
-            else:\r
-                EdkLogger.error("GenFds", BuildToolError.OPTION_VALUE_INVALID,\r
-                                "No such an FV in FDF file: %s" % Options.uiFvName)\r
-\r
-        """Call GenFds"""\r
-        GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
-    except FdfParser.Warning, X:\r
-        EdkLogger.error(X.ToolName, BuildToolError.FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError = False)\r
-        ReturnCode = BuildToolError.FORMAT_INVALID\r
-    except FatalError, X:\r
-        if Options.debug != None:\r
-            import traceback\r
-            EdkLogger.quiet(traceback.format_exc())\r
-        ReturnCode = X.args[0]\r
-    except:\r
-        import traceback\r
-        EdkLogger.error(\r
-                    "\nPython",\r
-                    CODE_ERROR,\r
-                    "Tools code failure",\r
-                    ExtraData="Please submit bug report in www.TianoCore.org, attaching following call stack trace!\n",\r
-                    RaiseError=False\r
-                    )\r
-        EdkLogger.quiet(traceback.format_exc())\r
-        ReturnCode = CODE_ERROR\r
-    return ReturnCode\r
-\r
-## Parse command line options\r
-#\r
-# Using standard Python module optparse to parse command line option of this tool.\r
-#\r
-#   @retval Opt   A optparse.Values object containing the parsed options\r
-#   @retval Args  Target of build command\r
-#\r
-def myOptionParser():\r
-    usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -y \"MacroName [= MacroValue]\""\r
-    Parser = OptionParser(usage=usage,description=__copyright__,version="%prog " + str(versionNumber))\r
-    Parser.add_option("-f", "--file", dest="filename", help="Name of FDF file to convert")\r
-    Parser.add_option("-a", "--arch", dest="archList", help="comma separated list containing one or more of: IA32, X64, IPF or EBC which should be built, overrides target.txt?s TARGET_ARCH")\r
-    Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
-    Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
-    Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
-    Parser.add_option("-p", "--platform", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.")\r
-    Parser.add_option("-w", "--workspace", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE")\r
-    Parser.add_option("-o", "--outputDir", dest="outputDir", help="Name of Build Output directory")\r
-    Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")\r
-    Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Buld the FV image using the [FV] section named by UiFvName")\r
-    Parser.add_option("-b", "--buildtarget", action="store", type="choice", choices=['DEBUG','RELEASE'], dest="BuildTarget", help="Build TARGET is one of list: DEBUG, RELEASE.")\r
-    Parser.add_option("-t", "--tagname", action="store", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.")\r
-    Parser.add_option("-y", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")\r
-    (Options, args) = Parser.parse_args()\r
-    return Options\r
-\r
-## The class implementing the EDK2 flash image generation process\r
-#\r
-#   This process includes:\r
-#       1. Collect workspace information, includes platform and module information\r
-#       2. Call methods of Fd class to generate FD\r
-#       3. Call methods of Fv class to generate FV that not belong to FD\r
-#\r
-class GenFds :\r
-    FdfParsef = None\r
-    # FvName in FDF, FvBinFile name\r
-    FvBinDict = {}\r
-    OnlyGenerateThisFd = None\r
-    OnlyGenerateThisFv = None\r
-\r
-    ## GenFd()\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 GenFd (OutputDir, FdfParser, WorkSpace, ArchList):\r
-        GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)\r
-\r
-        GenFdsGlobalVariable.VerboseLogger("   Gen Fd  !")\r
-        if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
-            FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())\r
-            if FdObj != None:\r
-                FdObj.GenFd(GenFds.FvBinDict)\r
-        elif GenFds.OnlyGenerateThisFv == None:\r
-            for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
-                FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
-                FdObj.GenFd(GenFds.FvBinDict)\r
-\r
-        GenFdsGlobalVariable.VerboseLogger(" Gen FV ! ")\r
-        if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
-            FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())\r
-            if FvObj != None:\r
-                Buffer = StringIO.StringIO()\r
-                # Get FV base Address\r
-                FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj))\r
-                Buffer.close()\r
-                return\r
-        elif GenFds.OnlyGenerateThisFd == None:\r
-            for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
-                Buffer = StringIO.StringIO('')\r
-                FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
-                # Get FV base Address\r
-                FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj))\r
-                Buffer.close()\r
-\r
-        if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None:\r
-            GenFdsGlobalVariable.VerboseLogger(" Gen Capsule !")\r
-            for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleList:\r
-                CapsuleObj.GenCapsule()\r
-\r
-    ## GetFvBlockSize()\r
-    #\r
-    #   @param  FvObj           Whose block size to get\r
-    #   @retval int             Block size value\r
-    #\r
-    def GetFvBlockSize(FvObj):\r
-        FdObj = None\r
-        if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
-            FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
-        if FdObj == None:\r
-            for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
-                for ElementRegion in ElementFd.RegionList:\r
-                    if ElementRegion.RegionType == 'FV':\r
-                        for ElementRegionData in ElementRegion.RegionDataList:\r
-                            if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
-                                if FvObj.BlockSizeList != []:\r
-                                    return FvObj.BlockSizeList[0][0]\r
-                                else:\r
-                                    return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
-            return 0x10000\r
-        else:\r
-            for ElementRegion in FdObj.RegionList:\r
-                    if ElementRegion.RegionType == 'FV':\r
-                        for ElementRegionData in ElementRegion.RegionDataList:\r
-                            if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
-                                if FvObj.BlockSizeList != []:\r
-                                    return FvObj.BlockSizeList[0][0]\r
-                                else:\r
-                                    return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
-            return 0x10000\r
-\r
-    ##Define GenFd as static function\r
-    GenFd = staticmethod(GenFd)\r
-    GetFvBlockSize = staticmethod(GetFvBlockSize)\r
-\r
-if __name__ == '__main__':\r
-    sys.exit(main())\r
-\r
+## @file
+# generate flash image
+#
+#  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
+#
+from optparse import OptionParser
+import sys
+import os
+import FdfParser
+from Common import BuildToolError
+from GenFdsGlobalVariable import GenFdsGlobalVariable
+from Workspace.WorkspaceDatabase import WorkspaceDatabase
+import RuleComplexFile
+from EfiSection import EfiSection
+import StringIO
+import Common.TargetTxtClassObject as TargetTxtClassObject
+import Common.DataType
+import Common.GlobalData as GlobalData
+from Common import EdkLogger
+from Common.String import *
+
+## Version and Copyright
+versionNumber = "1.0"
+__version__ = "%prog Version " + versionNumber
+__copyright__ = "Copyright (c) 2007, Intel Corporation  All rights reserved."
+
+## 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():
+    global Options
+    Options = myOptionParser()
+    global Workspace
+    Workspace = ""
+    ArchList = None
+    ReturnCode = 0
+
+    EdkLogger.Initialize()
+    try:
+        if Options.verbose != None:
+            EdkLogger.SetLevel(EdkLogger.VERBOSE)
+            GenFdsGlobalVariable.VerboseMode = True
+        if Options.quiet != None:
+            EdkLogger.SetLevel(EdkLogger.QUIET)
+        if Options.debug != None:
+            EdkLogger.SetLevel(Options.debug + 1)
+            GenFdsGlobalVariable.DebugLevel = Options.debug
+        else:
+            EdkLogger.SetLevel(EdkLogger.INFO)
+
+        if (Options.Workspace == None):
+            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "WORKSPACE not defined",
+                            ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
+        else:
+            Workspace = Options.Workspace
+            GenFdsGlobalVariable.WorkSpaceDir = Workspace
+            if 'EDK_SOURCE' in os.environ.keys():
+                GenFdsGlobalVariable.EdkSourceDir = os.environ['EDK_SOURCE']
+            if (Options.debug):
+                GenFdsGlobalVariable.VerboseLogger( "Using Workspace:" + Workspace)
+        os.chdir(GenFdsGlobalVariable.WorkSpaceDir)
+
+        if (Options.filename):
+            FdfFilename = Options.filename
+            FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)
+        else:
+            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing FDF filename")
+
+        if (Options.BuildTarget):
+            GenFdsGlobalVariable.TargetName = Options.BuildTarget
+        else:
+            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing build target")
+
+        if (Options.ToolChain):
+            GenFdsGlobalVariable.ToolChainTag = Options.ToolChain
+        else:
+            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing tool chain tag")
+
+        if FdfFilename[0:2] == '..':
+            FdfFilename = os.path.realpath(FdfFilename)
+        if FdfFilename[1] != ':':
+            FdfFilename = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)
+
+        if not os.path.exists(FdfFilename):
+            EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=FdfFilename)
+        GenFdsGlobalVariable.FdfFile = FdfFilename
+        GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename)
+
+        if (Options.activePlatform):
+            ActivePlatform = Options.activePlatform
+            ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform)
+
+            if ActivePlatform[0:2] == '..':
+                ActivePlatform = os.path.realpath(ActivePlatform)
+
+            if ActivePlatform[1] != ':':
+                ActivePlatform = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)
+
+            if not os.path.exists(ActivePlatform)  :
+                EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist!")
+
+            if ActivePlatform.find(Workspace) == -1:
+                EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist in Workspace!")
+
+            ActivePlatform = ActivePlatform.replace(Workspace, '')
+            if len(ActivePlatform) > 0 :
+                if ActivePlatform[0] == '\\' or ActivePlatform[0] == '/':
+                    ActivePlatform = ActivePlatform[1:]
+            else:
+                EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist!")
+        else :
+            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing active platform")
+
+        GenFdsGlobalVariable.ActivePlatform = NormPath(ActivePlatform)
+
+        if (Options.archList) :
+            ArchList = Options.archList.split(',')
+        else:
+            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing build ARCH")
+
+        BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, "Conf/target.txt"))
+        if os.path.isfile(BuildConfigurationFile) == True:
+            TargetTxtClassObject.TargetTxtClassObject(BuildConfigurationFile)
+        else:
+            EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=BuildConfigrationFile)
+
+        if Options.Macros:
+            for Pair in Options.Macros:
+                Pair.strip('"')
+                List = Pair.split('=')
+                if len(List) == 2:
+                    FdfParser.InputMacroDict[List[0].strip()] = List[1].strip()
+                    GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip()
+                else:
+                    FdfParser.InputMacroDict[List[0].strip()] = None
+
+        """call Workspace build create database"""
+        os.environ["WORKSPACE"] = Workspace
+        BuildWorkSpace = WorkspaceDatabase(':memory:', GlobalData.gGlobalDefines)
+        BuildWorkSpace.InitDatabase()
+
+        for Arch in ArchList:
+            GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[ActivePlatform, Arch].OutputDirectory)
+
+        if (Options.outputDir):
+            OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir)
+            for Arch in ArchList:
+                GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine
+        else:
+            for Arch in ArchList:
+                GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)
+
+        for Key in GenFdsGlobalVariable.OutputDirDict:
+            OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]
+            if OutputDir[0:2] == '..':
+                OutputDir = os.path.realpath(OutputDir)
+
+            if OutputDir[1] != ':':
+                OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)
+
+            if not os.path.exists(OutputDir):
+                EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=OutputDir)
+            GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir
+
+        """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """
+        FdfParserObj = FdfParser.FdfParser(FdfFilename)
+        FdfParserObj.ParseFile()
+
+        if FdfParserObj.CycleReferenceCheck():
+            EdkLogger.error("GenFds", BuildToolError.FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")
+
+        if (Options.uiFdName) :
+            if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys():
+                GenFds.currentFd = Options.uiFdName
+            else:
+                EdkLogger.error("GenFds", BuildToolError.OPTION_VALUE_INVALID,
+                                "No such an FD in FDF file: %s" % Options.uiFdName)
+
+        if (Options.uiFvName) :
+            if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys():
+                GenFds.currentFv = Options.uiFvName
+            else:
+                EdkLogger.error("GenFds", BuildToolError.OPTION_VALUE_INVALID,
+                                "No such an FV in FDF file: %s" % Options.uiFvName)
+
+        """Call GenFds"""
+        GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)
+    except FdfParser.Warning, X:
+        EdkLogger.error(X.ToolName, BuildToolError.FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError = False)
+        ReturnCode = BuildToolError.FORMAT_INVALID
+    except FatalError, X:
+        if Options.debug != None:
+            import traceback
+            EdkLogger.quiet(traceback.format_exc())
+        ReturnCode = X.args[0]
+    except:
+        import traceback
+        EdkLogger.error(
+                    "\nPython",
+                    CODE_ERROR,
+                    "Tools code failure",
+                    ExtraData="Please submit bug report in www.TianoCore.org, attaching following call stack trace!\n",
+                    RaiseError=False
+                    )
+        EdkLogger.quiet(traceback.format_exc())
+        ReturnCode = CODE_ERROR
+    return ReturnCode
+
+## 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():
+    usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -y \"MacroName [= MacroValue]\""
+    Parser = OptionParser(usage=usage,description=__copyright__,version="%prog " + str(versionNumber))
+    Parser.add_option("-f", "--file", dest="filename", help="Name of FDF file to convert")
+    Parser.add_option("-a", "--arch", dest="archList", help="comma separated list containing one or more of: IA32, X64, IPF or EBC which should be built, overrides target.txt?s TARGET_ARCH")
+    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.")
+    Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
+    Parser.add_option("-p", "--platform", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.")
+    Parser.add_option("-w", "--workspace", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE")
+    Parser.add_option("-o", "--outputDir", dest="outputDir", help="Name of Build Output directory")
+    Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")
+    Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Buld the FV image using the [FV] section named by UiFvName")
+    Parser.add_option("-b", "--buildtarget", action="store", type="choice", choices=['DEBUG','RELEASE'], dest="BuildTarget", help="Build TARGET is one of list: DEBUG, RELEASE.")
+    Parser.add_option("-t", "--tagname", action="store", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.")
+    Parser.add_option("-y", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")
+    (Options, args) = Parser.parse_args()
+    return Options
+
+## The class implementing the EDK2 flash image generation process
+#
+#   This process includes:
+#       1. Collect workspace information, includes platform and module information
+#       2. Call methods of Fd class to generate FD
+#       3. Call methods of Fv class to generate FV that not belong to FD
+#
+class GenFds :
+    FdfParsef = None
+    # FvName in FDF, FvBinFile name
+    FvBinDict = {}
+    OnlyGenerateThisFd = None
+    OnlyGenerateThisFv = None
+
+    ## GenFd()
+    #
+    #   @param  OutputDir           Output directory
+    #   @param  FdfParser           FDF contents parser
+    #   @param  Workspace           The directory of workspace
+    #   @param  ArchList            The Arch list of platform
+    #
+    def GenFd (OutputDir, FdfParser, WorkSpace, ArchList):
+        GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)
+
+        GenFdsGlobalVariable.VerboseLogger("   Gen Fd  !")
+        if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
+            FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())
+            if FdObj != None:
+                FdObj.GenFd(GenFds.FvBinDict)
+        elif GenFds.OnlyGenerateThisFv == None:
+            for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
+                FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]
+                FdObj.GenFd(GenFds.FvBinDict)
+
+        GenFdsGlobalVariable.VerboseLogger(" Gen FV ! ")
+        if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
+            FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())
+            if FvObj != None:
+                Buffer = StringIO.StringIO()
+                # Get FV base Address
+                FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj))
+                Buffer.close()
+                return
+        elif GenFds.OnlyGenerateThisFd == None:
+            for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
+                Buffer = StringIO.StringIO('')
+                FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]
+                # Get FV base Address
+                FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj))
+                Buffer.close()
+
+        if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None:
+            GenFdsGlobalVariable.VerboseLogger(" Gen Capsule !")
+            for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleList:
+                CapsuleObj.GenCapsule()
+
+    ## GetFvBlockSize()
+    #
+    #   @param  FvObj           Whose block size to get
+    #   @retval int             Block size value
+    #
+    def GetFvBlockSize(FvObj):
+        FdObj = None
+        if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
+            FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]
+        if FdObj == None:
+            for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():
+                for ElementRegion in ElementFd.RegionList:
+                    if ElementRegion.RegionType == 'FV':
+                        for ElementRegionData in ElementRegion.RegionDataList:
+                            if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:
+                                if FvObj.BlockSizeList != []:
+                                    return FvObj.BlockSizeList[0][0]
+                                else:
+                                    return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)
+            return 0x10000
+        else:
+            for ElementRegion in FdObj.RegionList:
+                    if ElementRegion.RegionType == 'FV':
+                        for ElementRegionData in ElementRegion.RegionDataList:
+                            if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:
+                                if FvObj.BlockSizeList != []:
+                                    return FvObj.BlockSizeList[0][0]
+                                else:
+                                    return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)
+            return 0x10000
+
+    ##Define GenFd as static function
+    GenFd = staticmethod(GenFd)
+    GetFvBlockSize = staticmethod(GetFvBlockSize)
+
+if __name__ == '__main__':
+    sys.exit(main())
+
index 1ad2a76..800e608 100644 (file)
-## @file\r
-# Global variables for GenFds\r
-#\r
-#  Copyright (c) 2007, 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 sys\r
-import subprocess\r
-import struct\r
-import array\r
-from Common import BuildToolError\r
-from Common import EdkLogger\r
-from Common.Misc import SaveFileOnChange\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
-    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
-\r
-    SectionHeader = struct.Struct("3B 1B")\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]], 'FV')\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
-        if ArchList != None:\r
-            GenFdsGlobalVariable.ArchList = ArchList\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].BsBaseAddress:\r
-                BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].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].RtBaseAddress:\r
-                RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].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
-        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 = os.path.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 == None or len(Input) == 0:\r
-            return True\r
-        OutputTime = os.path.getmtime(Output)\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=None, Ui=None, Ver=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 = ["GenSec"]\r
-        if Type not in [None, '']:\r
-            Cmd += ["-s", Type]\r
-        if CompressionType not in [None, '']:\r
-            Cmd += ["-c", CompressionType]\r
-        if Guid != None:\r
-            Cmd += ["-g", Guid]\r
-        if GuidHdrLen not in [None, '']:\r
-            Cmd += ["-l", GuidHdrLen]\r
-        if GuidAttr not in [None, '']:\r
-            Cmd += ["-r", GuidAttr]\r
-\r
-        if Ui not in [None, '']:\r
-            #Cmd += ["-n", '"' + Ui + '"']\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
-        elif Ver not in [None, '']:\r
-            #Cmd += ["-j", Ver]\r
-            SectionData = array.array('B', [0,0,0,0])\r
-            SectionData.fromstring(Ver.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
-        else:\r
-            Cmd += ["-o", Output]\r
-            Cmd += Input\r
-            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r
-\r
-    @staticmethod\r
-    def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,\r
-                    SectionAlign=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 = ["GenFfs", "-t", Type, "-g", Guid]\r
-        if Fixed == True:\r
-            Cmd += ["-x"]\r
-        if CheckSum:\r
-            Cmd += ["-s"]\r
-        if Align not in [None, '']:\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 not in [None, '', []] and SectionAlign[I] not in [None, '']:\r
-                Cmd += ("-n", SectionAlign[I])\r
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")\r
-\r
-    @staticmethod\r
-    def GenerateFirmwareVolume(Output, Input, BaseAddress=None, Capsule=False, Dump=False,\r
-                               AddressFile=None, MapFile=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 = ["GenFv"]\r
-        if BaseAddress not in [None, '']:\r
-            Cmd += ["-r", BaseAddress]\r
-        if Capsule:\r
-            Cmd += ["-c"]\r
-        if Dump:\r
-            Cmd += ["-p"]\r
-        if AddressFile not in [None, '']:\r
-            Cmd += ["-a", AddressFile]\r
-        if MapFile not in [None, '']:\r
-            Cmd += ["-m", MapFile]\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 not in [None, ''] and FvSize not in [None, ''] \\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):\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 = ["GenFw"]\r
-        if Type.lower() == "te":\r
-            Cmd += ["-t"]\r
-        if SubType not in [None, '']:\r
-            Cmd += ["-e", SubType]\r
-        if TimeStamp not in [None, '']:\r
-            Cmd += ["-s", TimeStamp]\r
-        if Align not in [None, '']:\r
-            Cmd += ["-a", Align]\r
-        if Padding not in [None, '']:\r
-            Cmd += ["-p", Padding]\r
-        if Zero:\r
-            Cmd += ["-z"]\r
-        if Strip:\r
-            Cmd += ["-l"]\r
-        if Replace:\r
-            Cmd += ["-r"]\r
-        if Join:\r
-            Cmd += ["-j"]\r
-        if Convert:\r
-            Cmd += ["-m"]\r
-        Cmd += ["-o", Output]\r
-        Cmd += Input\r
-\r
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")\r
-\r
-    @staticmethod\r
-    def GuidTool(Output, Input, ToolPath, Options=''):\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 = [ToolPath, Options]\r
-        Cmd += ["-o", Output]\r
-        Cmd += Input\r
-\r
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath)\r
-\r
-    def CallExternalTool (cmd, errorMess):\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 += ('-d', 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
-        PopenObject = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr= subprocess.PIPE)\r
-        (out, error) = PopenObject.communicate()\r
-\r
-        while PopenObject.returncode == None :\r
-            PopenObject.wait()\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
-                EdkLogger.error("GenFds", BuildToolError.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', BuildToolError.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 = 'COMMON'):\r
-        if Str == 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
-               }\r
-        OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]\r
-        if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList:\r
-            OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]\r
-\r
-        Dict['$(OUTPUT_DIRECTORY)'] = OutputDir\r
-\r
-        if MacroDict != None  and len (MacroDict) != 0:\r
-            Dict.update(MacroDict)\r
-\r
-        for key in Dict.keys():\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
-\r
-    SetDir = staticmethod(SetDir)\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
+## @file
+# Global variables for GenFds
+#
+#  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 sys
+import subprocess
+import struct
+import array
+from Common import BuildToolError
+from Common import EdkLogger
+from Common.Misc import SaveFileOnChange
+
+## 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
+
+    SectionHeader = struct.Struct("3B 1B")
+
+    ## 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=None, Ui=None, Ver=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 GuidAttr not in [None, '']:
+            Cmd += ["-r", GuidAttr]
+
+        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, 0x15)
+            SaveFileOnChange(Output,  SectionData.tostring())
+        else:
+            Cmd += ["-o", Output]
+            Cmd += Input
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
+
+    @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, Capsule=False, Dump=False,
+                               AddressFile=None, MapFile=None):
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
+            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 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 GuidTool(Output, Input, ToolPath, Options=''):
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
+            return
+        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
+
+        Cmd = [ToolPath, Options]
+        Cmd += ["-o", Output]
+        Cmd += Input
+
+        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath)
+
+    def CallExternalTool (cmd, errorMess):
+
+        if type(cmd) not in (tuple, list):
+            GenFdsGlobalVariable.ErrorLogger("ToolError!  Invalid parameter type in call to CallExternalTool")
+
+        if GenFdsGlobalVariable.DebugLevel != -1:
+            cmd += ('-d', 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')
+
+        PopenObject = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr= subprocess.PIPE)
+        (out, error) = PopenObject.communicate()
+
+        while PopenObject.returncode == None :
+            PopenObject.wait()
+        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:
+                EdkLogger.error("GenFds", BuildToolError.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', BuildToolError.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
+
+
+    SetDir = staticmethod(SetDir)
+    ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro)
+    CallExternalTool = staticmethod(CallExternalTool)
+    VerboseLogger = staticmethod(VerboseLogger)
+    InfLogger = staticmethod(InfLogger)
+    ErrorLogger = staticmethod(ErrorLogger)
+    DebugLogger = staticmethod(DebugLogger)
+    MacroExtend = staticmethod (MacroExtend)