]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/GenFds/GenFds.py
BaseTools: skip updating temporary variable.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GenFds.py
index aa8c04123ac8f6e453668fd999f3ac53dbe38014..810a1f86e948943372199c75c8ab5eb729621052 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # generate flash image\r
 #\r
 ## @file\r
 # generate flash image\r
 #\r
-#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\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
 #\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
@@ -24,7 +24,6 @@ import Common.BuildToolError as BuildToolError
 from GenFdsGlobalVariable import GenFdsGlobalVariable\r
 from Workspace.WorkspaceDatabase import WorkspaceDatabase\r
 from Workspace.BuildClassObject import PcdClassObject\r
 from GenFdsGlobalVariable import GenFdsGlobalVariable\r
 from Workspace.WorkspaceDatabase import WorkspaceDatabase\r
 from Workspace.BuildClassObject import PcdClassObject\r
-from Workspace.BuildClassObject import ModuleBuildClassObject\r
 import RuleComplexFile\r
 from EfiSection import EfiSection\r
 import StringIO\r
 import RuleComplexFile\r
 from EfiSection import EfiSection\r
 import StringIO\r
@@ -38,9 +37,11 @@ from Common.Misc import DirCache, PathClass
 from Common.Misc import SaveFileOnChange\r
 from Common.Misc import ClearDuplicatedInf\r
 from Common.Misc import GuidStructureStringToGuidString\r
 from Common.Misc import SaveFileOnChange\r
 from Common.Misc import ClearDuplicatedInf\r
 from Common.Misc import GuidStructureStringToGuidString\r
-from Common.Misc import CheckPcdDatum\r
 from Common.BuildVersion import gBUILD_VERSION\r
 from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 from Common.BuildVersion import gBUILD_VERSION\r
 from Common.MultipleWorkspace import MultipleWorkspace as mws\r
+import FfsFileStatement\r
+import glob\r
+from struct import unpack\r
 \r
 ## Version and Copyright\r
 versionNumber = "1.0" + ' ' + gBUILD_VERSION\r
 \r
 ## Version and Copyright\r
 versionNumber = "1.0" + ' ' + gBUILD_VERSION\r
@@ -67,22 +68,22 @@ def main():
 \r
     EdkLogger.Initialize()\r
     try:\r
 \r
     EdkLogger.Initialize()\r
     try:\r
-        if Options.verbose != None:\r
+        if Options.verbose is not None:\r
             EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
             GenFdsGlobalVariable.VerboseMode = True\r
             \r
             EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
             GenFdsGlobalVariable.VerboseMode = True\r
             \r
-        if Options.FixedAddress != None:\r
+        if Options.FixedAddress is not None:\r
             GenFdsGlobalVariable.FixedLoadAddress = True\r
             \r
             GenFdsGlobalVariable.FixedLoadAddress = True\r
             \r
-        if Options.quiet != None:\r
+        if Options.quiet is not None:\r
             EdkLogger.SetLevel(EdkLogger.QUIET)\r
             EdkLogger.SetLevel(EdkLogger.QUIET)\r
-        if Options.debug != None:\r
+        if Options.debug is not None:\r
             EdkLogger.SetLevel(Options.debug + 1)\r
             GenFdsGlobalVariable.DebugLevel = Options.debug\r
         else:\r
             EdkLogger.SetLevel(EdkLogger.INFO)\r
 \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
+        if (Options.Workspace is None):\r
             EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",\r
                             ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
         elif not os.path.exists(Options.Workspace):\r
             EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",\r
                             ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
         elif not os.path.exists(Options.Workspace):\r
@@ -95,6 +96,8 @@ def main():
                 GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE'])\r
             if (Options.debug):\r
                 GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace)\r
                 GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE'])\r
             if (Options.debug):\r
                 GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace)\r
+            if Options.GenfdsMultiThread:\r
+                GenFdsGlobalVariable.EnableGenfdsMultiThread = True\r
         os.chdir(GenFdsGlobalVariable.WorkSpaceDir)\r
         \r
         # set multiple workspace\r
         os.chdir(GenFdsGlobalVariable.WorkSpaceDir)\r
         \r
         # set multiple workspace\r
@@ -138,6 +141,7 @@ def main():
         else:\r
             EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")\r
 \r
         else:\r
             EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")\r
 \r
+        GlobalData.BuildOptionPcd     = Options.OptionPcd if Options.OptionPcd else {}\r
         GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform))\r
 \r
         if (Options.ConfDirectory):\r
         GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform))\r
 \r
         if (Options.ConfDirectory):\r
@@ -158,6 +162,8 @@ def main():
                 # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf\r
                 ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')\r
         GenFdsGlobalVariable.ConfDir = ConfDirectoryPath\r
                 # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf\r
                 ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')\r
         GenFdsGlobalVariable.ConfDir = ConfDirectoryPath\r
+        if not GlobalData.gConfDirectory:\r
+            GlobalData.gConfDirectory = GenFdsGlobalVariable.ConfDir\r
         BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt"))\r
         if os.path.isfile(BuildConfigurationFile) == True:\r
             TargetTxt = TargetTxtClassObject.TargetTxtClassObject()\r
         BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt"))\r
         if os.path.isfile(BuildConfigurationFile) == True:\r
             TargetTxt = TargetTxtClassObject.TargetTxtClassObject()\r
@@ -172,7 +178,7 @@ def main():
             # if no tool chain given in command line, get it from target.txt\r
             if not GenFdsGlobalVariable.ToolChainTag:\r
                 ToolChainList = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]\r
             # if no tool chain given in command line, get it from target.txt\r
             if not GenFdsGlobalVariable.ToolChainTag:\r
                 ToolChainList = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]\r
-                if ToolChainList == None or len(ToolChainList) == 0:\r
+                if ToolChainList is None or len(ToolChainList) == 0:\r
                     EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.")\r
                 if len(ToolChainList) != 1:\r
                     EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for ToolChain.")\r
                     EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.")\r
                 if len(ToolChainList) != 1:\r
                     EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for ToolChain.")\r
@@ -293,12 +299,10 @@ def main():
                                 "No such a Capsule in FDF file: %s" % Options.uiCapName)\r
 \r
         GenFdsGlobalVariable.WorkSpace = BuildWorkSpace\r
                                 "No such a Capsule in FDF file: %s" % Options.uiCapName)\r
 \r
         GenFdsGlobalVariable.WorkSpace = BuildWorkSpace\r
-        if ArchList != None:\r
+        if ArchList is not None:\r
             GenFdsGlobalVariable.ArchList = ArchList\r
 \r
             GenFdsGlobalVariable.ArchList = ArchList\r
 \r
-        if Options.OptionPcd:\r
-            GlobalData.BuildOptionPcd = Options.OptionPcd\r
-            CheckBuildOptionPcd()\r
+        # Dsc Build Data will handle Pcd Settings from CommandLine.\r
 \r
         """Modify images from build output if the feature of loading driver at fixed address is on."""\r
         if GenFdsGlobalVariable.FixedLoadAddress:\r
 \r
         """Modify images from build output if the feature of loading driver at fixed address is on."""\r
         if GenFdsGlobalVariable.FixedLoadAddress:\r
@@ -326,7 +330,7 @@ def main():
         GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
 \r
         """Generate GUID cross reference file"""\r
         GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
 \r
         """Generate GUID cross reference file"""\r
-        GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList)\r
+        GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj)\r
 \r
         """Display FV space info."""\r
         GenFds.DisplayFvSpaceInfo(FdfParserObj)\r
 \r
         """Display FV space info."""\r
         GenFds.DisplayFvSpaceInfo(FdfParserObj)\r
@@ -335,7 +339,7 @@ def main():
         EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
         ReturnCode = FORMAT_INVALID\r
     except FatalError, X:\r
         EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
         ReturnCode = FORMAT_INVALID\r
     except FatalError, X:\r
-        if Options.debug != None:\r
+        if Options.debug is not None:\r
             import traceback\r
             EdkLogger.quiet(traceback.format_exc())\r
         ReturnCode = X.args[0]\r
             import traceback\r
             EdkLogger.quiet(traceback.format_exc())\r
         ReturnCode = X.args[0]\r
@@ -362,78 +366,6 @@ def SingleCheckCallback(option, opt_str, value, parser):
     else:\r
         parser.error("Option %s only allows one instance in command line!" % option)\r
 \r
     else:\r
         parser.error("Option %s only allows one instance in command line!" % option)\r
 \r
-def CheckBuildOptionPcd():\r
-    for Arch in GenFdsGlobalVariable.ArchList:\r
-        PkgList  = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)\r
-        for i, pcd in enumerate(GlobalData.BuildOptionPcd):\r
-            if type(pcd) is tuple:\r
-                continue\r
-            (pcdname, pcdvalue) = pcd.split('=')\r
-            if not pcdvalue:\r
-                EdkLogger.error('GenFds', OPTION_MISSING, "No Value specified for the PCD %s." % (pcdname))\r
-            if '.' in pcdname:\r
-                (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')\r
-                HasTokenSpace = True\r
-            else:\r
-                TokenCName = pcdname\r
-                TokenSpaceGuidCName = ''\r
-                HasTokenSpace = False\r
-            TokenSpaceGuidCNameList = []\r
-            FoundFlag = False\r
-            PcdDatumType = ''\r
-            NewValue = ''\r
-            for package in PkgList:\r
-                for key in package.Pcds:\r
-                    PcdItem = package.Pcds[key]\r
-                    if HasTokenSpace:\r
-                        if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):\r
-                            PcdDatumType = PcdItem.DatumType\r
-                            NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
-                            FoundFlag = True\r
-                    else:\r
-                        if PcdItem.TokenCName == TokenCName:\r
-                            if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:\r
-                                if len (TokenSpaceGuidCNameList) < 1:\r
-                                    TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)\r
-                                    PcdDatumType = PcdItem.DatumType\r
-                                    TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName\r
-                                    NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
-                                    FoundFlag = True\r
-                                else:\r
-                                    EdkLogger.error(\r
-                                            'GenFds',\r
-                                            PCD_VALIDATION_INFO_ERROR,\r
-                                            "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])\r
-                                            )\r
-\r
-            GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)\r
-\r
-def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):\r
-    if PcdDatumType == 'VOID*':\r
-        if Value.startswith('L'):\r
-            if not Value[1]:\r
-                EdkLogger.error('GenFds', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')\r
-            Value = Value[0] + '"' + Value[1:] + '"'\r
-        elif Value.startswith('B'):\r
-            if not Value[1]:\r
-                EdkLogger.error('GenFds', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')\r
-            Value = Value[1:]\r
-        else:\r
-            if not Value[0]:\r
-                EdkLogger.error('GenFds', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')\r
-            Value = '"' + Value + '"'\r
-\r
-    IsValid, Cause = CheckPcdDatum(PcdDatumType, Value)\r
-    if not IsValid:\r
-        EdkLogger.error('build', FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))\r
-    if PcdDatumType == 'BOOLEAN':\r
-        Value = Value.upper()\r
-        if Value == 'TRUE' or Value == '1':\r
-            Value = '1'\r
-        elif Value == 'FALSE' or Value == '0':\r
-            Value = '0'\r
-    return  Value\r
-\r
 ## FindExtendTool()\r
 #\r
 #  Find location of tools to process data\r
 ## FindExtendTool()\r
 #\r
 #  Find location of tools to process data\r
@@ -445,7 +377,7 @@ def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Val
 def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):\r
     ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase\r
     # if user not specify filter, try to deduce it from global data.\r
 def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):\r
     ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase\r
     # if user not specify filter, try to deduce it from global data.\r
-    if KeyStringList == None or KeyStringList == []:\r
+    if KeyStringList is None or KeyStringList == []:\r
         Target = GenFdsGlobalVariable.TargetName\r
         ToolChain = GenFdsGlobalVariable.ToolChainTag\r
         if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:\r
         Target = GenFdsGlobalVariable.TargetName\r
         ToolChain = GenFdsGlobalVariable.ToolChainTag\r
         if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:\r
@@ -466,7 +398,7 @@ def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
     ToolOptionKey = None\r
     KeyList = None\r
     for ToolDef in ToolDefinition.items():\r
     ToolOptionKey = None\r
     KeyList = None\r
     for ToolDef in ToolDefinition.items():\r
-        if NameGuid == ToolDef[1]:\r
+        if NameGuid.lower() == ToolDef[1].lower() :\r
             KeyList = ToolDef[0].split('_')\r
             Key = KeyList[0] + \\r
                   '_' + \\r
             KeyList = ToolDef[0].split('_')\r
             Key = KeyList[0] + \\r
                   '_' + \\r
@@ -478,7 +410,7 @@ def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
                 ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'\r
                 ToolPath = ToolDefinition.get(ToolPathKey)\r
                 ToolOption = ToolDefinition.get(ToolOptionKey)\r
                 ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'\r
                 ToolPath = ToolDefinition.get(ToolPathKey)\r
                 ToolOption = ToolDefinition.get(ToolOptionKey)\r
-                if ToolPathTmp == None:\r
+                if ToolPathTmp is None:\r
                     ToolPathTmp = ToolPath\r
                 else:\r
                     if ToolPathTmp != ToolPath:\r
                     ToolPathTmp = ToolPath\r
                 else:\r
                     if ToolPathTmp != ToolPath:\r
@@ -559,6 +491,7 @@ def myOptionParser():
     Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")\r
     Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")\r
     Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")\r
     Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")\r
     Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")\r
     Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")\r
+    Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.")\r
 \r
     (Options, args) = Parser.parse_args()\r
     return Options\r
 \r
     (Options, args) = Parser.parse_args()\r
     return Options\r
@@ -589,38 +522,38 @@ class GenFds :
         GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)\r
 \r
         GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")\r
         GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)\r
 \r
         GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")\r
-        if GenFds.OnlyGenerateThisCap != None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
+        if GenFds.OnlyGenerateThisCap is not None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
             CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.get(GenFds.OnlyGenerateThisCap.upper())\r
             CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.get(GenFds.OnlyGenerateThisCap.upper())\r
-            if CapsuleObj != None:\r
+            if CapsuleObj is not None:\r
                 CapsuleObj.GenCapsule()\r
                 return\r
 \r
                 CapsuleObj.GenCapsule()\r
                 return\r
 \r
-        if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
+        if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
             FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())\r
             FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())\r
-            if FdObj != None:\r
+            if FdObj is not None:\r
                 FdObj.GenFd()\r
                 return\r
                 FdObj.GenFd()\r
                 return\r
-        elif GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisFv == None:\r
+        elif GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisFv is None:\r
             for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
                 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
                 FdObj.GenFd()\r
 \r
         GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")\r
             for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
                 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
                 FdObj.GenFd()\r
 \r
         GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")\r
-        if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
+        if GenFds.OnlyGenerateThisFv is not None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
             FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())\r
             FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())\r
-            if FvObj != None:\r
+            if FvObj is not None:\r
                 Buffer = StringIO.StringIO()\r
                 FvObj.AddToBuffer(Buffer)\r
                 Buffer.close()\r
                 return\r
                 Buffer = StringIO.StringIO()\r
                 FvObj.AddToBuffer(Buffer)\r
                 Buffer.close()\r
                 return\r
-        elif GenFds.OnlyGenerateThisFv == None:\r
+        elif GenFds.OnlyGenerateThisFv is None:\r
             for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
                 Buffer = StringIO.StringIO('')\r
                 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
                 FvObj.AddToBuffer(Buffer)\r
                 Buffer.close()\r
         \r
             for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
                 Buffer = StringIO.StringIO('')\r
                 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
                 FvObj.AddToBuffer(Buffer)\r
                 Buffer.close()\r
         \r
-        if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisCap == None:\r
+        if GenFds.OnlyGenerateThisFv is None and GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisCap is None:\r
             if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:\r
                 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")\r
                 for CapsuleName in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
             if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:\r
                 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")\r
                 for CapsuleName in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
@@ -632,6 +565,23 @@ class GenFds :
                 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():\r
                     OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]\r
                     OptRomObj.AddToBuffer(None)\r
                 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():\r
                     OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]\r
                     OptRomObj.AddToBuffer(None)\r
+    @staticmethod\r
+    def GenFfsMakefile(OutputDir, FdfParser, WorkSpace, ArchList, GlobalData):\r
+        GenFdsGlobalVariable.SetEnv(FdfParser, WorkSpace, ArchList, GlobalData)\r
+        for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
+            FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
+            FdObj.GenFd(Flag=True)\r
+\r
+        for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
+            FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
+            FvObj.AddToBuffer(Buffer=None, Flag=True)\r
+\r
+        if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
+            for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():\r
+                OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]\r
+                OptRomObj.AddToBuffer(Buffer=None, Flag=True)\r
+\r
+        return GenFdsGlobalVariable.FfsCmdDict\r
 \r
     ## GetFvBlockSize()\r
     #\r
 \r
     ## GetFvBlockSize()\r
     #\r
@@ -641,14 +591,14 @@ class GenFds :
     def GetFvBlockSize(FvObj):\r
         DefaultBlockSize = 0x1\r
         FdObj = None\r
     def GetFvBlockSize(FvObj):\r
         DefaultBlockSize = 0x1\r
         FdObj = None\r
-        if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
+        if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
             FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
             FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
-        if FdObj == None:\r
+        if FdObj is 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
             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 ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:\r
                                 if FvObj.BlockSizeList != []:\r
                                     return FvObj.BlockSizeList[0][0]\r
                                 else:\r
                                 if FvObj.BlockSizeList != []:\r
                                     return FvObj.BlockSizeList[0][0]\r
                                 else:\r
@@ -660,7 +610,7 @@ class GenFds :
             for ElementRegion in FdObj.RegionList:\r
                     if ElementRegion.RegionType == 'FV':\r
                         for ElementRegionData in ElementRegion.RegionDataList:\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 ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:\r
                                 if FvObj.BlockSizeList != []:\r
                                     return FvObj.BlockSizeList[0][0]\r
                                 else:\r
                                 if FvObj.BlockSizeList != []:\r
                                     return FvObj.BlockSizeList[0][0]\r
                                 else:\r
@@ -748,14 +698,20 @@ class GenFds :
             ModuleObj = BuildDb.BuildObject[Key, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
             print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType\r
 \r
             ModuleObj = BuildDb.BuildObject[Key, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
             print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType\r
 \r
-    def GenerateGuidXRefFile(BuildDb, ArchList):\r
+    def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj):\r
         GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")\r
         GuidXRefFile = StringIO.StringIO('')\r
         GuidDict = {}\r
         GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")\r
         GuidXRefFile = StringIO.StringIO('')\r
         GuidDict = {}\r
+        ModuleList = []\r
+        FileGuidList = []\r
         for Arch in ArchList:\r
             PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
             for ModuleFile in PlatformDataBase.Modules:\r
                 Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
         for Arch in ArchList:\r
             PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
             for ModuleFile in PlatformDataBase.Modules:\r
                 Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
+                if Module in ModuleList:\r
+                    continue\r
+                else:\r
+                    ModuleList.append(Module)\r
                 GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))\r
                 for key, item in Module.Protocols.items():\r
                     GuidDict[key] = item\r
                 GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))\r
                 for key, item in Module.Protocols.items():\r
                     GuidDict[key] = item\r
@@ -763,6 +719,81 @@ class GenFds :
                     GuidDict[key] = item\r
                 for key, item in Module.Ppis.items():\r
                     GuidDict[key] = item\r
                     GuidDict[key] = item\r
                 for key, item in Module.Ppis.items():\r
                     GuidDict[key] = item\r
+            for FvName in FdfParserObj.Profile.FvDict:\r
+                for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList:\r
+                    if not isinstance(FfsObj, FfsFileStatement.FileStatement):\r
+                        InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName)))\r
+                        FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
+                        if FdfModule in ModuleList:\r
+                            continue\r
+                        else:\r
+                            ModuleList.append(FdfModule)\r
+                        GuidXRefFile.write("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName))\r
+                        for key, item in FdfModule.Protocols.items():\r
+                            GuidDict[key] = item\r
+                        for key, item in FdfModule.Guids.items():\r
+                            GuidDict[key] = item\r
+                        for key, item in FdfModule.Ppis.items():\r
+                            GuidDict[key] = item\r
+                    else:\r
+                        FileStatementGuid = FfsObj.NameGuid\r
+                        if FileStatementGuid in FileGuidList:\r
+                            continue\r
+                        else:\r
+                            FileGuidList.append(FileStatementGuid)\r
+                        Name = []\r
+                        FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
+                        FfsPath = glob.glob(os.path.join(FfsPath, FileStatementGuid) + '*')\r
+                        if not FfsPath:\r
+                            continue\r
+                        if not os.path.exists(FfsPath[0]):\r
+                            continue\r
+                        MatchDict = {}\r
+                        ReFileEnds = re.compile('\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.te.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$')\r
+                        FileList = os.listdir(FfsPath[0])\r
+                        for File in FileList:\r
+                            Match = ReFileEnds.search(File)\r
+                            if Match:\r
+                                for Index in range(1, 8):\r
+                                    if Match.group(Index) and Match.group(Index) in MatchDict:\r
+                                        MatchDict[Match.group(Index)].append(File)\r
+                                    elif Match.group(Index):\r
+                                        MatchDict[Match.group(Index)] = [File]\r
+                        if not MatchDict:\r
+                            continue\r
+                        if '.ui' in MatchDict:\r
+                            for File in MatchDict['.ui']:\r
+                                with open(os.path.join(FfsPath[0], File), 'rb') as F:\r
+                                    F.read()\r
+                                    length = F.tell()\r
+                                    F.seek(4)\r
+                                    TmpStr = unpack('%dh' % ((length - 4) / 2), F.read())\r
+                                    Name = ''.join([chr(c) for c in TmpStr[:-1]])\r
+                        else:\r
+                            FileList = []\r
+                            if 'fv.sec.txt' in MatchDict:\r
+                                FileList = MatchDict['fv.sec.txt']\r
+                            elif '.pe32.txt' in MatchDict:\r
+                                FileList = MatchDict['.pe32.txt']\r
+                            elif '.te.txt' in MatchDict:\r
+                                FileList = MatchDict['.te.txt']\r
+                            elif '.pic.txt' in MatchDict:\r
+                                FileList = MatchDict['.pic.txt']\r
+                            elif '.raw.txt' in MatchDict:\r
+                                FileList = MatchDict['.raw.txt']\r
+                            elif '.ffs.txt' in MatchDict:\r
+                                FileList = MatchDict['.ffs.txt']\r
+                            else:\r
+                                pass\r
+                            for File in FileList:\r
+                                with open(os.path.join(FfsPath[0], File), 'r') as F:\r
+                                    Name.append((F.read().split()[-1]))\r
+                        if not Name:\r
+                            continue\r
+\r
+                        Name = ' '.join(Name) if type(Name) == type([]) else Name\r
+                        GuidXRefFile.write("%s %s\n" %(FileStatementGuid, Name))\r
+\r
        # Append GUIDs, Protocols, and PPIs to the Xref file\r
         GuidXRefFile.write("\n")\r
         for key, item in GuidDict.items():\r
        # Append GUIDs, Protocols, and PPIs to the Xref file\r
         GuidXRefFile.write("\n")\r
         for key, item in GuidDict.items():\r