[edk2] [Patch 3/3] BaseTools: Update Makefile to support FFS file generation

Yonghong Zhu posted 3 patches 7 years, 2 months ago
There is a newer version of this series
[edk2] [Patch 3/3] BaseTools: Update Makefile to support FFS file generation
Posted by Yonghong Zhu 7 years, 2 months ago
Update Makefile to support FFS file generation.

Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
---
 BaseTools/Source/Python/AutoGen/AutoGen.py         |  16 +-
 BaseTools/Source/Python/AutoGen/GenMake.py         |  84 +++++++++
 BaseTools/Source/Python/GenFds/AprioriSection.py   |  16 +-
 BaseTools/Source/Python/GenFds/CompressSection.py  |  10 +-
 BaseTools/Source/Python/GenFds/DataSection.py      |  37 ++--
 BaseTools/Source/Python/GenFds/DepexSection.py     |   6 +-
 BaseTools/Source/Python/GenFds/EfiSection.py       |  78 ++++----
 BaseTools/Source/Python/GenFds/Fd.py               |  24 ++-
 BaseTools/Source/Python/GenFds/FfsFileStatement.py |   4 +-
 BaseTools/Source/Python/GenFds/FfsInfStatement.py  | 198 ++++++++++++---------
 BaseTools/Source/Python/GenFds/Fv.py               | 187 ++++++++++---------
 BaseTools/Source/Python/GenFds/FvImageSection.py   |   8 +-
 BaseTools/Source/Python/GenFds/GenFds.py           |  17 ++
 .../Source/Python/GenFds/GenFdsGlobalVariable.py   | 168 +++++++++++++----
 BaseTools/Source/Python/GenFds/GuidSection.py      |  59 +-----
 .../Source/Python/GenFds/OptRomFileStatement.py    |   4 +-
 .../Source/Python/GenFds/OptRomInfStatement.py     |  12 +-
 BaseTools/Source/Python/GenFds/OptionRom.py        |  25 +--
 BaseTools/Source/Python/GenFds/Region.py           |  49 +++--
 BaseTools/Source/Python/GenFds/Section.py          |   4 +-
 BaseTools/Source/Python/GenFds/UiSection.py        |   5 +-
 BaseTools/Source/Python/GenFds/VerSection.py       |   9 +-
 BaseTools/Source/Python/build/build.py             |  18 +-
 23 files changed, 656 insertions(+), 382 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index 14eb138..981f0a6 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -2757,10 +2757,11 @@ class ModuleAutoGen(AutoGen):
         self._CustomMakefile  = None
         self._Macro           = None
 
         self._BuildDir        = None
         self._OutputDir       = None
+        self._FfsOutputDir    = None
         self._DebugDir        = None
         self._MakeFileDir     = None
 
         self._IncludePathList = None
         self._IncludePathLength = 0
@@ -2873,10 +2874,11 @@ class ModuleAutoGen(AutoGen):
             self._Macro["PLATFORM_GUID"         ] = self.PlatformInfo.Guid
             self._Macro["PLATFORM_VERSION"      ] = self.PlatformInfo.Version
             self._Macro["PLATFORM_RELATIVE_DIR" ] = self.PlatformInfo.SourceDir
             self._Macro["PLATFORM_DIR"          ] = mws.join(self.WorkspaceDir, self.PlatformInfo.SourceDir)
             self._Macro["PLATFORM_OUTPUT_DIR"   ] = self.PlatformInfo.OutputDir
+            self._Macro["FFS_OUTPUT_DIR"        ] = self.FfsOutputDir
         return self._Macro
 
     ## Return the module build data object
     def _GetModule(self):
         if self._Module == None:
@@ -2963,10 +2965,19 @@ class ModuleAutoGen(AutoGen):
         if self._OutputDir == None:
             self._OutputDir = path.join(self.BuildDir, "OUTPUT")
             CreateDirectory(self._OutputDir)
         return self._OutputDir
 
+    ## Return the directory to store ffs file
+    def _GetFfsOutputDir(self):
+        if self._FfsOutputDir == None:
+            if GlobalData.gFdfParser != None:
+                self._FfsOutputDir = path.join(self.PlatformInfo.BuildDir, "FV", "Ffs", self.Guid + self.Name)
+            else:
+                self._FfsOutputDir = ''
+        return self._FfsOutputDir
+
     ## Return the directory to store auto-gened source files of the mdoule
     def _GetDebugDir(self):
         if self._DebugDir == None:
             self._DebugDir = path.join(self.BuildDir, "DEBUG")
             CreateDirectory(self._DebugDir)
@@ -4219,20 +4230,20 @@ class ModuleAutoGen(AutoGen):
     ## Create makefile for the module and its dependent libraries
     #
     #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of
     #                                       dependent libraries will be created
     #
-    def CreateMakeFile(self, CreateLibraryMakeFile=True):
+    def CreateMakeFile(self, CreateLibraryMakeFile=True, GenFfsList = []):
         # Ignore generating makefile when it is a binary module
         if self.IsBinaryModule:
             return
 
         if self.IsMakeFileCreated:
             return
         if self.CanSkip():
             return
-
+        self.GenFfsList = GenFfsList
         if not self.IsLibrary and CreateLibraryMakeFile:
             for LibraryAutoGen in self.LibraryAutoGenList:
                 LibraryAutoGen.CreateMakeFile()
 
         if len(self.CustomMakefile) == 0:
@@ -4452,10 +4463,11 @@ class ModuleAutoGen(AutoGen):
 
     IsLibrary       = property(_IsLibrary)
     IsBinaryModule  = property(_IsBinaryModule)
     BuildDir        = property(_GetBuildDir)
     OutputDir       = property(_GetOutputDir)
+    FfsOutputDir    = property(_GetFfsOutputDir)
     DebugDir        = property(_GetDebugDir)
     MakeFileDir     = property(_GetMakeFileDir)
     CustomMakefile  = property(_GetCustomMakefile)
 
     IncludePathList = property(_GetIncludePathList)
diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py
index 942eb44..814a503 100644
--- a/BaseTools/Source/Python/AutoGen/GenMake.py
+++ b/BaseTools/Source/Python/AutoGen/GenMake.py
@@ -141,10 +141,15 @@ class BuildFile(object):
     ## directory removal template
     _RD_TEMPLATE_ = {
         "nmake" :   'if exist %(dir)s $(RD) %(dir)s',
         "gmake" :   "$(RD) %(dir)s"
     }
+    ## cp if exist
+    _CP_TEMPLATE_ = {
+        "nmake" :   'if exist %(Src)s $(CP) %(Src)s %(Dst)s',
+        "gmake" :   "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"
+    }
 
     _CD_TEMPLATE_ = {
         "nmake" :   'if exist %(dir)s cd %(dir)s',
         "gmake" :   "test -e %(dir)s && cd %(dir)s"
     }
@@ -248,10 +253,11 @@ MODULE_FILE = ${module_file}
 MODULE_FILE_BASE_NAME = ${module_file_base_name}
 BASE_NAME = $(MODULE_NAME)
 MODULE_RELATIVE_DIR = ${module_relative_directory}
 PACKAGE_RELATIVE_DIR = ${package_relative_directory}
 MODULE_DIR = ${module_dir}
+FFS_OUTPUT_DIR = ${ffs_output_directory}
 
 MODULE_ENTRY_POINT = ${module_entry_point}
 ARCH_ENTRY_POINT = ${arch_entry_point}
 IMAGE_ENTRY_POINT = ${image_entry_point}
 
@@ -439,10 +445,14 @@ cleanlib:
         self.Macros["DEBUG_DIR"       ] = self._AutoGenObject.Macros["DEBUG_DIR"]
         self.Macros["MODULE_BUILD_DIR"] = self._AutoGenObject.Macros["MODULE_BUILD_DIR"]
         self.Macros["BIN_DIR"         ] = self._AutoGenObject.Macros["BIN_DIR"]
         self.Macros["BUILD_DIR"       ] = self._AutoGenObject.Macros["BUILD_DIR"]
         self.Macros["WORKSPACE"       ] = self._AutoGenObject.Macros["WORKSPACE"]
+        self.Macros["FFS_OUTPUT_DIR"  ] = self._AutoGenObject.Macros["FFS_OUTPUT_DIR"]
+        self.GenFfsList                 = ModuleAutoGen.GenFfsList
+        self.MacroList = ['FFS_OUTPUT_DIR', 'MODULE_GUID', 'OUTPUT_DIR']
+        self.FfsOutputFileList = []
 
     # Compose a dict object containing information used to do replacement in template
     def _CreateTemplateDict(self):
         if self._FileType not in self._SEP_:
             EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,
@@ -553,10 +563,11 @@ cleanlib:
         if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:
             EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",
                             ExtraData="[%s]" % str(self._AutoGenObject))
 
         self.ProcessBuildTargetList()
+        self.ParserGenerateFfsCmd()
 
         # Generate macros used to represent input files
         FileMacroList = [] # macro name = file list
         for FileListMacro in self.FileListMacros:
             FileMacro = self._FILE_MACRO_TEMPLATE.Replace(
@@ -625,10 +636,11 @@ cleanlib:
             "platform_name"             : self.PlatformInfo.Name,
             "platform_guid"             : self.PlatformInfo.Guid,
             "platform_version"          : self.PlatformInfo.Version,
             "platform_relative_directory": self.PlatformInfo.SourceDir,
             "platform_output_directory" : self.PlatformInfo.OutputDir,
+            "ffs_output_directory"      : self._AutoGenObject.Macros["FFS_OUTPUT_DIR"],
             "platform_dir"              : self._AutoGenObject.Macros["PLATFORM_DIR"],
 
             "module_name"               : self._AutoGenObject.Name,
             "module_guid"               : self._AutoGenObject.Guid,
             "module_name_guid"          : self._AutoGenObject._GetUniqueBaseName(),
@@ -671,10 +683,82 @@ cleanlib:
             "backward_compatible_target": BcTargetList,
         }
 
         return MakefileTemplateDict
 
+    def ParserGenerateFfsCmd(self):
+        #Add Ffs cmd to self.BuildTargetList
+        OutputFile = ''
+        DepsFileList = []
+
+        for Cmd in self.GenFfsList:
+            if Cmd[2]:
+                for CopyCmd in Cmd[2]:
+                    Src, Dst = CopyCmd
+                    Src = self.ReplaceMacro(Src)
+                    Dst = self.ReplaceMacro(Dst)
+                    if Dst not in self.ResultFileList:
+                        self.ResultFileList.append('%s' % Dst)
+                    if '%s :' %(Dst) not in self.BuildTargetList:
+                        self.BuildTargetList.append("%s :" %(Dst))
+                        self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._FileType] %{'Src': Src, 'Dst': Dst})
+
+            FfsCmdList = Cmd[0]
+            for index, Str in enumerate(FfsCmdList):
+                if '-o' == Str:
+                    OutputFile = FfsCmdList[index + 1]
+                if '-i' == Str:
+                    if DepsFileList == []:
+                        DepsFileList = [FfsCmdList[index + 1]]
+                    else:
+                        DepsFileList.append(FfsCmdList[index + 1])
+            DepsFileString = ' '.join(DepsFileList).strip()
+            if DepsFileString == '':
+                continue
+            OutputFile = self.ReplaceMacro(OutputFile)
+            self.ResultFileList.append('%s' % OutputFile)
+            DepsFileString = self.ReplaceMacro(DepsFileString)
+            self.BuildTargetList.append('%s : %s' % (OutputFile, DepsFileString))
+            CmdString = ' '.join(FfsCmdList).strip()
+            CmdString = self.ReplaceMacro(CmdString)
+            self.BuildTargetList.append('\t%s' % CmdString)
+
+            self.ParseSecCmd(DepsFileList, Cmd[1])
+            for SecOutputFile, SecDepsFile, SecCmd in self.FfsOutputFileList :
+                self.BuildTargetList.append('%s : %s' % (self.ReplaceMacro(SecOutputFile), self.ReplaceMacro(SecDepsFile)))
+                self.BuildTargetList.append('\t%s' % self.ReplaceMacro(SecCmd))
+            self.FfsOutputFileList = []
+
+    def ParseSecCmd(self, OutputFileList, CmdTuple):
+        for OutputFile in OutputFileList:
+            for SecCmdStr in CmdTuple:
+                SecDepsFileList = []
+                SecCmdList = SecCmdStr.split()
+                CmdName = SecCmdList[0]
+                for index, CmdItem in enumerate(SecCmdList):
+                    if '-o' == CmdItem and OutputFile == SecCmdList[index + 1]:
+                        index = index + 1
+                        while index + 1 < len(SecCmdList):
+                            if not SecCmdList[index+1].startswith('-'):
+                                SecDepsFileList.append(SecCmdList[index + 1])
+                            index = index + 1
+                        if CmdName == 'Trim':
+                            SecDepsFileList.append(os.path.join('$(DEBUG_DIR)', os.path.basename(OutputFile).replace('offset', 'efi')))
+                        if OutputFile.endswith('.ui') or OutputFile.endswith('.ver'):
+                            SecDepsFileList.append(os.path.join('$(MODULE_DIR)','$(MODULE_FILE)'))
+                        self.FfsOutputFileList.append((OutputFile, ' '.join(SecDepsFileList), SecCmdStr))
+                        if len(SecDepsFileList) > 0:
+                            self.ParseSecCmd(SecDepsFileList, CmdTuple)
+                        break
+                    else:
+                        continue
+
+    def ReplaceMacro(self, str):
+        for Macro in self.MacroList:
+            str = str.replace(self._AutoGenObject.Macros[Macro], '$(' + Macro + ')')
+        return str
+
     def CommandExceedLimit(self):
         FlagDict = {
                     'CC'    :  { 'Macro' : '$(CC_FLAGS)',    'Value' : False},
                     'PP'    :  { 'Macro' : '$(PP_FLAGS)',    'Value' : False},
                     'APP'   :  { 'Macro' : '$(APP_FLAGS)',   'Value' : False},
diff --git a/BaseTools/Source/Python/GenFds/AprioriSection.py b/BaseTools/Source/Python/GenFds/AprioriSection.py
index a2306d0..34e56b0 100644
--- a/BaseTools/Source/Python/GenFds/AprioriSection.py
+++ b/BaseTools/Source/Python/GenFds/AprioriSection.py
@@ -1,9 +1,9 @@
 ## @file
 # process APRIORI file data and generate PEI/DXE APRIORI file
 #
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -45,11 +45,11 @@ class AprioriSection (AprioriSectionClassObject):
     #   @param  self        The object pointer
     #   @param  FvName      for whom apriori file generated
     #   @param  Dict        dictionary contains macro and its value
     #   @retval string      Generated file name
     #
-    def GenFfs (self, FvName, Dict = {}):
+    def GenFfs (self, FvName, Dict = {}, IsMakefile = False):
         DXE_GUID = "FC510EE7-FFDC-11D4-BD41-0080C73C8881"
         PEI_GUID = "1B45CC0A-156A-428A-AF62-49864DA0E6E6"
         Buffer = StringIO.StringIO('')
         AprioriFileGuid = DXE_GUID
         if self.AprioriType == "PEI":
@@ -64,13 +64,16 @@ class AprioriSection (AprioriSectionClassObject):
                                        AprioriFileGuid + FvName + '.Apri' )
         AprFfsFileName = os.path.join (OutputAprFilePath,\
                                     AprioriFileGuid + FvName + '.Ffs')
 
         Dict.update(self.DefineVarDict)
+        InfFileName = None
         for FfsObj in self.FfsList :
             Guid = ""
             if isinstance(FfsObj, FfsFileStatement.FileStatement):
+                if IsMakefile:
+                    continue
                 Guid = FfsObj.NameGuid
             else:
                 InfFileName = NormPath(FfsObj.InfFileName)
                 Arch = FfsObj.GetCurrentArch()
 
@@ -108,11 +111,16 @@ class AprioriSection (AprioriSectionClassObject):
 
         SaveFileOnChange(OutputAprFileName, Buffer.getvalue())
 
         RawSectionFileName = os.path.join( OutputAprFilePath, \
                                        AprioriFileGuid + FvName + '.raw' )
-        GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW')
+        MakefilePath = None
+        if IsMakefile:
+            if not InfFileName:
+                return None
+            MakefilePath = InfFileName, Arch
+        GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW', IsMakefile=IsMakefile)
         GenFdsGlobalVariable.GenerateFfs(AprFfsFileName, [RawSectionFileName],
-                                         'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid)
+                                        'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid, MakefilePath=MakefilePath)
 
         return AprFfsFileName
 
diff --git a/BaseTools/Source/Python/GenFds/CompressSection.py b/BaseTools/Source/Python/GenFds/CompressSection.py
index fac58d1..64ad275 100644
--- a/BaseTools/Source/Python/GenFds/CompressSection.py
+++ b/BaseTools/Source/Python/GenFds/CompressSection.py
@@ -1,9 +1,9 @@
 ## @file
 # process compress section generation
 #
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -51,25 +51,25 @@ class CompressSection (CompressSectionClassObject) :
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}, IsMakefile = False):
 
         if FfsInf != None:
             self.CompType = FfsInf.__ExtendMacro__(self.CompType)
             self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
 
         SectFiles = tuple()
         Index = 0
         for Sect in self.SectionList:
             Index = Index + 1
             SecIndex = '%s.%d' %(SecNum, Index)
-            ReturnSectList, AlignValue = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict)
+            ReturnSectList, AlignValue = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile)
             if ReturnSectList != []:
                 for FileData in ReturnSectList:
-                   SectFiles += (FileData,)
+                    SectFiles += (FileData,)
 
 
         OutputFile = OutputPath + \
                      os.sep     + \
                      ModuleName + \
@@ -77,11 +77,11 @@ class CompressSection (CompressSectionClassObject) :
                      SecNum     + \
                      Ffs.SectionSuffix['COMPRESS']
         OutputFile = os.path.normpath(OutputFile)
 
         GenFdsGlobalVariable.GenerateSection(OutputFile, SectFiles, Section.Section.SectionType['COMPRESS'],
-                                             CompressionType=self.CompTypeDict[self.CompType])
+                                             CompressionType=self.CompTypeDict[self.CompType], IsMakefile=IsMakefile)
         OutputFileList = []
         OutputFileList.append(OutputFile)
         return OutputFileList, self.Alignment
 
 
diff --git a/BaseTools/Source/Python/GenFds/DataSection.py b/BaseTools/Source/Python/GenFds/DataSection.py
index 78c0af4..2d2975f 100644
--- a/BaseTools/Source/Python/GenFds/DataSection.py
+++ b/BaseTools/Source/Python/GenFds/DataSection.py
@@ -46,11 +46,11 @@ class DataSection (DataSectionClassObject):
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name list, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}, IsMakefile = False):
         #
         # Prepare the parameter of GenSection
         #
         if FfsFile != None:
             self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName)
@@ -67,14 +67,20 @@ class DataSection (DataSectionClassObject):
 
         """Copy Map file to Ffs output"""
         Filename = GenFdsGlobalVariable.MacroExtend(self.SectFileName)
         if Filename[(len(Filename)-4):] == '.efi':
             MapFile = Filename.replace('.efi', '.map')
-            if os.path.exists(MapFile):
-                CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
-                if not os.path.exists(CopyMapFile) or (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
-                    CopyLongFilePath(MapFile, CopyMapFile)
+            CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
+            if IsMakefile:
+                if GenFdsGlobalVariable.CopyList == []:
+                    GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)]
+                else:
+                    GenFdsGlobalVariable.CopyList.append((MapFile, CopyMapFile))
+            else:
+                if os.path.exists(MapFile):
+                    if not os.path.exists(CopyMapFile) or (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
+                        CopyLongFilePath(MapFile, CopyMapFile)
 
         #Get PE Section alignment when align is set to AUTO
         if self.Alignment == 'Auto' and self.SecType in ('TE', 'PE32'):
             ImageObj = PeImageClass (Filename)
             if ImageObj.SectionAlignment < 0x400:
@@ -94,26 +100,27 @@ class DataSection (DataSectionClassObject):
             if not os.path.exists(FileBeforeStrip) or \
                 (os.path.getmtime(self.SectFileName) > os.path.getmtime(FileBeforeStrip)):
                 CopyLongFilePath(self.SectFileName, FileBeforeStrip)
             StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped')
             GenFdsGlobalVariable.GenerateFirmwareImage(
-                                    StrippedFile,
-                                    [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)],
-                                    Strip=True
-                                    )
+                    StrippedFile,
+                    [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)],
+                    Strip=True,
+                    IsMakefile = IsMakefile
+                )
             self.SectFileName = StrippedFile
 
         if self.SecType == 'TE':
             TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw')
             GenFdsGlobalVariable.GenerateFirmwareImage(
-                                    TeFile,
-                                    [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)],
-                                    Type='te'
-                                    )
+                    TeFile,
+                    [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)],
+                    Type='te',
+                    IsMakefile = IsMakefile
+                )
             self.SectFileName = TeFile
 
         OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get(self.SecType))
         OutputFile = os.path.normpath(OutputFile)
-
-        GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType))
+        GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType), IsMakefile = IsMakefile)
         FileList = [OutputFile]
         return FileList, self.Alignment
diff --git a/BaseTools/Source/Python/GenFds/DepexSection.py b/BaseTools/Source/Python/GenFds/DepexSection.py
index 8f78c0f..1992d2a 100644
--- a/BaseTools/Source/Python/GenFds/DepexSection.py
+++ b/BaseTools/Source/Python/GenFds/DepexSection.py
@@ -1,9 +1,9 @@
 ## @file
 # process depex section generation
 #
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -74,11 +74,11 @@ class DepexSection (DepexSectionClassObject):
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name list, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}, IsMakefile = False):
         
         if self.ExpressionProcessed == False:
             self.Expression = self.Expression.replace("\n", " ").replace("\r", " ")
             ExpList = self.Expression.split()
             ExpGuidDict = {}
@@ -117,8 +117,8 @@ class DepexSection (DepexSectionClassObject):
         Depex.Generate(InputFile)
 
         OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + '.dpx')
         OutputFile = os.path.normpath(OutputFile)
 
-        GenFdsGlobalVariable.GenerateSection(OutputFile, [InputFile], Section.Section.SectionType.get (SecType))
+        GenFdsGlobalVariable.GenerateSection(OutputFile, [InputFile], Section.Section.SectionType.get (SecType), IsMakefile=IsMakefile)
         FileList = [OutputFile]
         return FileList, self.Alignment
diff --git a/BaseTools/Source/Python/GenFds/EfiSection.py b/BaseTools/Source/Python/GenFds/EfiSection.py
index 7da3c1e..d34f744 100644
--- a/BaseTools/Source/Python/GenFds/EfiSection.py
+++ b/BaseTools/Source/Python/GenFds/EfiSection.py
@@ -51,11 +51,11 @@ class EfiSection (EfiSectionClassObject):
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name list, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}) :
+    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}, IsMakefile = False) :
         
         if self.FileName != None and self.FileName.startswith('PCD('):
             self.FileName = GenFdsGlobalVariable.GetPcdValue(self.FileName)
         """Prepare the parameter of GenSection"""
         if FfsInf != None :
@@ -87,11 +87,11 @@ class EfiSection (EfiSectionClassObject):
             else:
                 Filename = os.path.normpath(os.path.join(FfsInf.EfiOutputPath, Filename))
 
             if not self.Optional:
                 FileList.append(Filename)
-            elif os.path.exists(Filename):
+            elif '.depex' in FfsInf.FinalTargetSuffixMap or FfsInf.Depex:
                 FileList.append(Filename)
         else:
             FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FileType, self.FileExtension, Dict)
             if IsSect :
                 return FileList, self.Alignment
@@ -117,12 +117,13 @@ class EfiSection (EfiSectionClassObject):
                     BuildNumTuple = tuple()
 
                 Num = SecNum
                 OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
                 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
-                                                     #Ui=StringData, 
-                                                     Ver=BuildNum)
+                                                    #Ui=StringData,
+                                                    Ver=BuildNum,
+                                                    IsMakefile=IsMakefile)
                 OutputFileList.append(OutputFile)
 
             elif FileList != []:
                 for File in FileList:
                     Index = Index + 1
@@ -133,12 +134,13 @@ class EfiSection (EfiSectionClassObject):
                     f.close()
                     BuildNum = VerString
                     if BuildNum != None and BuildNum != '':
                         BuildNumTuple = ('-j', BuildNum)
                     GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
-                                                         #Ui=VerString, 
-                                                         Ver=BuildNum)
+                                                        #Ui=VerString,
+                                                        Ver=BuildNum,
+                                                        IsMakefile=IsMakefile)
                     OutputFileList.append(OutputFile)
 
             else:
                 BuildNum = StringData
                 if BuildNum != None and BuildNum != '':
@@ -155,12 +157,13 @@ class EfiSection (EfiSectionClassObject):
                     else:
                         EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss Version Section value" %InfFileName)
                 Num = SecNum
                 OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
                 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
-                                                     #Ui=VerString, 
-                                                     Ver=BuildNum)
+                                                    #Ui=VerString,
+                                                    Ver=BuildNum,
+                                                    IsMakefile=IsMakefile)
                 OutputFileList.append(OutputFile)
 
         #
         # If Section Type is 'UI'
         #
@@ -173,11 +176,11 @@ class EfiSection (EfiSectionClassObject):
 
             if InfOverrideUiString:
                 Num = SecNum
                 OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
                 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
-                                                     Ui=StringData)
+                                                     Ui=StringData, IsMakefile=IsMakefile)
                 OutputFileList.append(OutputFile)
 
             elif FileList != []:
                 for File in FileList:
                     Index = Index + 1
@@ -185,11 +188,11 @@ class EfiSection (EfiSectionClassObject):
                     OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType))
                     f = open(File, 'r')
                     UiString = f.read()
                     f.close()
                     GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
-                                                         Ui=UiString)
+                                                        Ui=UiString, IsMakefile=IsMakefile)
                     OutputFileList.append(OutputFile)
             else:
                 if StringData != None and len(StringData) > 0:
                     UiTuple = ('-n', '"' + StringData + '"')
                 else:
@@ -202,11 +205,11 @@ class EfiSection (EfiSectionClassObject):
                         EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss UI Section value" %InfFileName)
 
                 Num = SecNum
                 OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
                 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
-                                                     Ui=StringData)
+                                                     Ui=StringData, IsMakefile=IsMakefile)
                 OutputFileList.append(OutputFile)
 
 
         else:
             """If File List is empty"""
@@ -236,43 +239,58 @@ class EfiSection (EfiSectionClassObject):
                         else:
                             Align = str (ImageObj.SectionAlignment / 0x100000) + 'M'
 
                     if File[(len(File)-4):] == '.efi':
                         MapFile = File.replace('.efi', '.map')
-                        if os.path.exists(MapFile):
-                            CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
-                            if not os.path.exists(CopyMapFile) or \
-                                   (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
-                                CopyLongFilePath(MapFile, CopyMapFile)
+                        CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
+                        if IsMakefile:
+                            if GenFdsGlobalVariable.CopyList == []:
+                                GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)]
+                            else:
+                                GenFdsGlobalVariable.CopyList.append((MapFile, CopyMapFile))
+                        else:
+                            if os.path.exists(MapFile):
+                                if not os.path.exists(CopyMapFile) or \
+                                       (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
+                                    CopyLongFilePath(MapFile, CopyMapFile)
 
                     if not NoStrip:
                         FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi')
-                        if not os.path.exists(FileBeforeStrip) or \
-                            (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
-                            CopyLongFilePath(File, FileBeforeStrip)
+                        if IsMakefile:
+                            if GenFdsGlobalVariable.CopyList == []:
+                                GenFdsGlobalVariable.CopyList = [(File, FileBeforeStrip)]
+                            else:
+                                GenFdsGlobalVariable.CopyList.append((File, FileBeforeStrip))
+                        else:
+                            if not os.path.exists(FileBeforeStrip) or \
+                                (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
+                                CopyLongFilePath(File, FileBeforeStrip)
                         StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped')
                         GenFdsGlobalVariable.GenerateFirmwareImage(
-                                                StrippedFile,
-                                                [File],
-                                                Strip=True
-                                                )
+                                StrippedFile,
+                                [File],
+                                Strip=True,
+                                IsMakefile = IsMakefile
+                            )
                         File = StrippedFile
                     
                     """For TE Section call GenFw to generate TE image"""
 
                     if SectionType == 'TE':
                         TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw')
                         GenFdsGlobalVariable.GenerateFirmwareImage(
-                                                TeFile,
-                                                [File],
-                                                Type='te'
-                                                )
+                                TeFile,
+                                [File],
+                                Type='te',
+                                IsMakefile = IsMakefile
+                            )
                         File = TeFile
 
                     """Call GenSection"""
                     GenFdsGlobalVariable.GenerateSection(OutputFile,
-                                                         [File],
-                                                         Section.Section.SectionType.get (SectionType)
-                                                         )
+                                                        [File],
+                                                        Section.Section.SectionType.get (SectionType),
+                                                        IsMakefile=IsMakefile
+                                                        )
                     OutputFileList.append(OutputFile)
 
         return OutputFileList, Align
diff --git a/BaseTools/Source/Python/GenFds/Fd.py b/BaseTools/Source/Python/GenFds/Fd.py
index f330a7e..2ce3f21 100644
--- a/BaseTools/Source/Python/GenFds/Fd.py
+++ b/BaseTools/Source/Python/GenFds/Fd.py
@@ -43,19 +43,20 @@ class FD(FDClassObject):
     #
     #   Generate FD
     #
     #   @retval string      Generated FD file name
     #
-    def GenFd (self):
+    def GenFd (self, Flag = False):
         if self.FdUiName.upper() + 'fd' in GenFds.ImageBinDict.keys():
             return GenFds.ImageBinDict[self.FdUiName.upper() + 'fd']
 
         #
         # Print Information
         #
         FdFileName = os.path.join(GenFdsGlobalVariable.FvDir, self.FdUiName + '.fd')
-        GenFdsGlobalVariable.InfLogger("Fd File Name:%s (%s)" %(self.FdUiName, FdFileName))
+        if not Flag:
+            GenFdsGlobalVariable.InfLogger("Fd File Name:%s (%s)" %(self.FdUiName, FdFileName))
 
         Offset = 0x00
         for item in self.BlockSizeList:
             Offset = Offset + item[0]  * item[1]
         if Offset != self.Size:
@@ -83,15 +84,17 @@ class FD(FDClassObject):
                 if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
                     pass
                 elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
                     pass
                 elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
-                    GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
+                    if not Flag:
+                        GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
                     PadRegion = Region.Region()
                     PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
                     PadRegion.Size = RegionObj.Offset - PadRegion.Offset
-                    PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
+                    if not Flag:
+                        PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
                 PreviousRegionStart = RegionObj.Offset
                 PreviousRegionSize = RegionObj.Size
                 #
                 # Call each region's AddToBuffer function
                 #
@@ -111,15 +114,17 @@ class FD(FDClassObject):
             elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
                 EdkLogger.error("GenFds", GENFDS_ERROR,
                                 'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \
                                 % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
             elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
-                GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
+                if not Flag:
+                    GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
                 PadRegion = Region.Region()
                 PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
                 PadRegion.Size = RegionObj.Offset - PadRegion.Offset
-                PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
+                if not Flag:
+                    PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
             PreviousRegionStart = RegionObj.Offset
             PreviousRegionSize = RegionObj.Size
             #
             # Verify current region fits within allocated FD section Size
             #
@@ -129,17 +134,18 @@ class FD(FDClassObject):
                                 % (self.FdUiName, PreviousRegionStart, PreviousRegionSize))
             #
             # Call each region's AddToBuffer function
             #
             GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
-            RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
+            RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict,Flag=Flag)
         #
         # Write the buffer contents to Fd file
         #
         GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file')
-        SaveFileOnChange(FdFileName, FdBuffer.getvalue())
-        FdBuffer.close();
+        if not Flag:
+            SaveFileOnChange(FdFileName, FdBuffer.getvalue())
+        FdBuffer.close()
         GenFds.ImageBinDict[self.FdUiName.upper() + 'fd'] = FdFileName
         return FdFileName
 
     ## generate VTF
     #
diff --git a/BaseTools/Source/Python/GenFds/FfsFileStatement.py b/BaseTools/Source/Python/GenFds/FfsFileStatement.py
index f76ddf4..edb1312 100644
--- a/BaseTools/Source/Python/GenFds/FfsFileStatement.py
+++ b/BaseTools/Source/Python/GenFds/FfsFileStatement.py
@@ -1,9 +1,9 @@
 ## @file
 # process FFS generation from FILE statement
 #
-#  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -55,11 +55,11 @@ class FileStatement (FileStatementClassObject) :
     #   @param  Dict         dictionary contains macro and value pair
     #   @param  FvChildAddr  Array of the inside FvImage base address
     #   @param  FvParentAddr Parent Fv base address
     #   @retval string       Generated FFS file name
     #
-    def GenFfs(self, Dict = {}, FvChildAddr=[], FvParentAddr=None):
+    def GenFfs(self, Dict = {}, FvChildAddr=[], FvParentAddr=None, IsMakefile=False):
         
         if self.NameGuid != None and self.NameGuid.startswith('PCD('):
             PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid)
             if len(PcdValue) == 0:
                 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
index 958cecf..aee5a2f 100644
--- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py
+++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
@@ -42,10 +42,12 @@ from Common.Misc import PeImageClass
 from AutoGen.GenDepex import DependencyExpression
 from PatchPcdValue.PatchPcdValue import PatchBinaryFile
 from Common.LongFilePathSupport import CopyLongFilePath
 from Common.LongFilePathSupport import OpenLongFilePath as open
 import Common.GlobalData as GlobalData
+from DepexSection import DepexSection
+from Common.Misc import SaveFileOnChange
 
 ## generate FFS from INF
 #
 #
 class FfsInfStatement(FfsInfStatementClassObject):
@@ -70,10 +72,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
         self.FileName = None
         self.InfFileName = None
         self.OverrideGuid = None
         self.PatchedBinFile = ''
         self.MacroDict = {}
+        self.Depex = False
 
     ## GetFinalTargetSuffixMap() method
     #
     #    Get final build target list
     def GetFinalTargetSuffixMap(self):
@@ -318,10 +321,15 @@ class FfsInfStatement(FfsInfStatementClassObject):
             self.PatchPcds.append((Pcd, DefaultValue))
 
         self.InfModule = Inf
         self.PcdIsDriver = Inf.PcdIsDriver
         self.IsBinaryModule = Inf.IsBinaryModule
+        Inf._GetDepex()
+        Inf._GetDepexExpression()
+        if len(Inf._Depex.data) > 0 and len(Inf._DepexExpression.data) > 0:
+            self.Depex = True
+
         GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName)
         GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid)
         GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType)
         GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString)
         GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName)
@@ -333,11 +341,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
         self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \
                                        self.ModuleGuid + self.BaseName)
         if not os.path.exists(self.OutputPath) :
             os.makedirs(self.OutputPath)
 
-        self.EfiOutputPath = self.__GetEFIOutPutPath__()
+        self.EfiOutputPath, self.EfiDebugPath = self.__GetEFIOutPutPath__()
         GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)
 
     ## PatchEfiFile
     #
     #  Patch EFI file with patch PCD
@@ -412,16 +420,17 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  Dict         dictionary contains macro and value pair
     #   @param  FvChildAddr  Array of the inside FvImage base address
     #   @param  FvParentAddr Parent Fv base address
     #   @retval string       Generated FFS file name
     #
-    def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None):
+    def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None, IsMakefile=False):
         #
         # Parse Inf file get Module related information
         #
 
         self.__InfParse__(Dict)
+        Arch = self.GetCurrentArch()
         SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName);
         DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
         
         SrcFileDir = "."
         SrcPath = os.path.dirname(SrcFile)
@@ -470,21 +479,23 @@ class FfsInfStatement(FfsInfStatementClassObject):
             if Rule.FvFileType == 'SMM' or Rule.FvFileType == 'SMM_CORE':
                 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName)
         #
         # For the rule only has simpleFile
         #
+        MakefilePath = None
+        if IsMakefile:
+            MakefilePath = self.InfFileName, Arch
         if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :
-            SectionOutputList = self.__GenSimpleFileSection__(Rule)
-            FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList)
+            SectionOutputList = self.__GenSimpleFileSection__(Rule, IsMakefile=IsMakefile)
+            FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList, MakefilePath=MakefilePath)
             return FfsOutput
         #
         # For Rule has ComplexFile
         #
         elif isinstance(Rule, RuleComplexFile.RuleComplexFile):
-            InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr)
-            FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments)
-
+            InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr, IsMakefile=IsMakefile)
+            FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments, MakefilePath=MakefilePath)
             return FfsOutput
 
     ## __ExtendMacro__() method
     #
     #   Replace macro with its value
@@ -649,10 +660,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @retval string      Path that output files from this INF go to
     #
     def __GetEFIOutPutPath__(self):
         Arch = ''
         OutputPath = ''
+        DebugPath = ''
         (ModulePath, FileName) = os.path.split(self.InfFileName)
         Index = FileName.rfind('.')
         FileName = FileName[0:Index]
         if self.OverrideGuid:
             FileName = self.OverrideGuid
@@ -664,22 +676,29 @@ class FfsInfStatement(FfsInfStatementClassObject):
                                   Arch ,
                                   ModulePath,
                                   FileName,
                                   'OUTPUT'
                                   )
+        DebugPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],
+                                  Arch ,
+                                  ModulePath,
+                                  FileName,
+                                  'DEBUG'
+                                  )
         OutputPath = os.path.realpath(OutputPath)
-        return OutputPath
+        DebugPath = os.path.realpath(DebugPath)
+        return OutputPath, DebugPath
 
     ## __GenSimpleFileSection__() method
     #
     #   Generate section by specified file name or a list of files with file extension
     #
     #   @param  self        The object pointer
     #   @param  Rule        The rule object used to generate section
     #   @retval string      File name of the generated section file
     #
-    def __GenSimpleFileSection__(self, Rule):
+    def __GenSimpleFileSection__(self, Rule, IsMakefile = False):
         #
         # Prepare the parameter of GenSection
         #
         FileList = []
         OutputFileList = []
@@ -741,26 +760,27 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     if not os.path.exists(FileBeforeStrip) or \
                            (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
                         CopyLongFilePath(File, FileBeforeStrip)
                     StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
                     GenFdsGlobalVariable.GenerateFirmwareImage(
-                                            StrippedFile,
-                                            [File],
-                                            Strip=True
-                                            )
+                            StrippedFile,
+                            [File],
+                            Strip=True,
+                            IsMakefile=IsMakefile
+                        )
                     File = StrippedFile
 
                 if SectionType == 'TE':
                     TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
                     GenFdsGlobalVariable.GenerateFirmwareImage(
-                                            TeFile,
-                                            [File],
-                                            Type='te'
-                                            )
+                            TeFile,
+                            [File],
+                            Type='te',
+                            IsMakefile=IsMakefile
+                        )
                     File = TeFile
-
-                GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType])
+                GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile)
                 OutputFileList.append(OutputFile)
         else:
             SecNum = '%d' %Index
             GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
                               Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
@@ -783,26 +803,27 @@ class FfsInfStatement(FfsInfStatementClassObject):
                        (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):
                     CopyLongFilePath(GenSecInputFile, FileBeforeStrip)
 
                 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
                 GenFdsGlobalVariable.GenerateFirmwareImage(
-                                        StrippedFile,
-                                        [GenSecInputFile],
-                                        Strip=True
-                                        )
+                        StrippedFile,
+                        [GenSecInputFile],
+                        Strip=True,
+                        IsMakefile=IsMakefile
+                    )
                 GenSecInputFile = StrippedFile
 
             if SectionType == 'TE':
                 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
                 GenFdsGlobalVariable.GenerateFirmwareImage(
-                                        TeFile,
-                                        [GenSecInputFile],
-                                        Type='te'
-                                        )
+                        TeFile,
+                        [GenSecInputFile],
+                        Type='te',
+                        IsMakefile=IsMakefile
+                    )
                 GenSecInputFile = TeFile
-
-            GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType])
+            GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile)
             OutputFileList.append(OutputFile)
 
         return OutputFileList
 
     ## __GenSimpleFileFfs__() method
@@ -812,11 +833,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  self        The object pointer
     #   @param  Rule        The rule object used to generate section
     #   @param  InputFileList        The output file list from GenSection
     #   @retval string      Generated FFS file name
     #
-    def __GenSimpleFileFfs__(self, Rule, InputFileList):
+    def __GenSimpleFileFfs__(self, Rule, InputFileList, MakefilePath = None):
         FfsOutput = self.OutputPath                     + \
                     os.sep                              + \
                     self.__ExtendMacro__(Rule.NameGuid) + \
                     '.ffs'
 
@@ -838,16 +859,17 @@ class FfsInfStatement(FfsInfStatementClassObject):
             if len(RegistryGuidStr) == 0:
                 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
                             % (Rule.NameGuid))
             self.ModuleGuid = RegistryGuidStr
 
-        GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,
-                                         Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
-                                         self.ModuleGuid, Fixed=Rule.Fixed,
-                                         CheckSum=Rule.CheckSum, Align=Rule.Alignment,
-                                         SectionAlign=SectionAlignments
-                                        )
+            GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,
+                                             Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
+                                             self.ModuleGuid, Fixed=Rule.Fixed,
+                                             CheckSum=Rule.CheckSum, Align=Rule.Alignment,
+                                             SectionAlign=SectionAlignments,
+                                             MakefilePath=MakefilePath
+                                             )
         return FfsOutput
 
     ## __GenComplexFileSection__() method
     #
     #   Generate section by sections in Rule
@@ -856,40 +878,42 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  Rule         The rule object used to generate section
     #   @param  FvChildAddr  Array of the inside FvImage base address
     #   @param  FvParentAddr Parent Fv base address
     #   @retval string       File name of the generated section file
     #
-    def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr):
+    def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr, IsMakefile = False):
         if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
             if Rule.KeepReloc != None:
                 self.KeepRelocFromRule = Rule.KeepReloc
         SectFiles = []
         SectAlignments = []
         Index = 1
-        HasGneratedFlag = False
+        HasGeneratedFlag = False
         if self.PcdIsDriver == 'PEI_PCD_DRIVER':
             if self.IsBinaryModule:
                 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw")
             else:
                 PcdExDbFileName = os.path.join(self.EfiOutputPath, "PEIPcdDataBase.raw")
             PcdExDbSecName = os.path.join(self.OutputPath, "PEIPcdDataBaseSec.raw")
             GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
                                                  [PcdExDbFileName],
                                                  "EFI_SECTION_RAW",
+                                                 IsMakefile = IsMakefile
                                                  )
             SectFiles.append(PcdExDbSecName)
             SectAlignments.append(None)
         elif self.PcdIsDriver == 'DXE_PCD_DRIVER':
             if self.IsBinaryModule:
                 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "DXEPcdDataBase.raw")
             else:
                 PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw")
             PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw")
             GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
-                                                 [PcdExDbFileName],
-                                                 "EFI_SECTION_RAW",
-                                                 )
+                                                [PcdExDbFileName],
+                                                "EFI_SECTION_RAW",
+                                                IsMakefile = IsMakefile
+                                                )
             SectFiles.append(PcdExDbSecName)
             SectAlignments.append(None)
         for Sect in Rule.SectionList:
             SecIndex = '%d' %Index
             SectList  = []
@@ -915,15 +939,15 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     Sect.FvAddr = FvChildAddr
             if FvParentAddr != None and isinstance(Sect, GuidSection):
                 Sect.FvParentAddr = FvParentAddr
             
             if Rule.KeyStringList != []:
-                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self)
+                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self, IsMakefile = IsMakefile)
             else :
-                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)
+                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self, IsMakefile = IsMakefile)
             
-            if not HasGneratedFlag:
+            if not HasGeneratedFlag:
                 UniVfrOffsetFileSection = ""    
                 ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)
                 InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]
                 #
                 # Search the source list in InfData to find if there are .vfr file exist.
@@ -942,31 +966,44 @@ class FfsInfStatement(FfsInfStatementClassObject):
                         #
                         VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings")
                     
                 
                 if len(VfrUniBaseName) > 0:
-                    VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)
-                    #
-                    # Generate the Raw data of raw section
-                    #
-                    if VfrUniOffsetList:
-                        os.path.join( self.OutputPath, self.BaseName + '.offset')
-                        UniVfrOffsetFileName    =  os.path.join( self.OutputPath, self.BaseName + '.offset')
-                        UniVfrOffsetFileSection =  os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw')
-
-                        self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)
-
-                        UniVfrOffsetFileNameList = []
-                        UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)
-                        """Call GenSection"""
-                        GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,
-                                                             UniVfrOffsetFileNameList,
-                                                             "EFI_SECTION_RAW"
-                                                             )
-                        os.remove(UniVfrOffsetFileName)
+                    if IsMakefile:
+                        if InfData.BuildType != 'UEFI_HII':
+                            UniVfrOffsetFileName = os.path.join(self.OutputPath, self.BaseName + '.offset')
+                            UniVfrOffsetFileSection = os.path.join(self.OutputPath, self.BaseName + 'Offset' + '.raw')
+                            UniVfrOffsetFileNameList = []
+                            UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)
+                            TrimCmd = "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName, self.BaseName, self.EfiDebugPath)
+                            GenFdsGlobalVariable.SecCmdList.append(TrimCmd)
+                            GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,
+                                                                [UniVfrOffsetFileName],
+                                                                "EFI_SECTION_RAW",
+                                                                IsMakefile = True
+                                                                )
+                    else:
+                        VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)
+                        #
+                        # Generate the Raw data of raw section
+                        #
+                        if VfrUniOffsetList:
+                            UniVfrOffsetFileName = os.path.join(self.OutputPath, self.BaseName + '.offset')
+                            UniVfrOffsetFileSection = os.path.join(self.OutputPath, self.BaseName + 'Offset' + '.raw')
+                            self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)
+                            UniVfrOffsetFileNameList = []
+                            UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)
+                            """Call GenSection"""
+
+                            GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,
+                                                                 UniVfrOffsetFileNameList,
+                                                                 "EFI_SECTION_RAW"
+                                                                 )
+                            #os.remove(UniVfrOffsetFileName)
+                    if UniVfrOffsetFileSection:
                         SectList.append(UniVfrOffsetFileSection)
-                        HasGneratedFlag = True
+                        HasGeneratedFlag = True
                 
             for SecName in  SectList :
                 SectFiles.append(SecName)
                 SectAlignments.append(Align)
             Index = Index + 1
@@ -979,11 +1016,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  self        The object pointer
     #   @param  Rule        The rule object used to generate section
     #   @param  InputFileList        The output file list from GenSection
     #   @retval string      Generated FFS file name
     #
-    def __GenComplexFileFfs__(self, Rule, InputFile, Alignments):
+    def __GenComplexFileFfs__(self, Rule, InputFile, Alignments, MakefilePath = None):
 
         if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
             PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
             if len(PcdValue) == 0:
                 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
@@ -996,15 +1033,16 @@ class FfsInfStatement(FfsInfStatementClassObject):
                             % (Rule.NameGuid))
             self.ModuleGuid = RegistryGuidStr
 
         FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
         GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,
-                                         Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
-                                         self.ModuleGuid, Fixed=Rule.Fixed,
-                                         CheckSum=Rule.CheckSum, Align=Rule.Alignment,
-                                         SectionAlign=Alignments
-                                        )
+                                             Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
+                                             self.ModuleGuid, Fixed=Rule.Fixed,
+                                             CheckSum=Rule.CheckSum, Align=Rule.Alignment,
+                                             SectionAlign=Alignments,
+                                             MakefilePath=MakefilePath
+                                             )
         return FfsOutput
 
     ## __GetGenFfsCmdParameter__() method
     #
     #   Create parameter string for GenFfs
@@ -1046,16 +1084,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  self                    The object pointer
     #   @param  VfrUniOffsetList        A list contain the VFR/UNI offsets in the EFI image file.
     #   @param  UniVfrOffsetFileName    The output offset file name.
     #
     def __GenUniVfrOffsetFile(self, VfrUniOffsetList, UniVfrOffsetFileName):
-        
-        try:
-            fInputfile = open(UniVfrOffsetFileName, "wb+", 0)
-        except:
-            EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %UniVfrOffsetFileName,None)
-            
+
         # Use a instance of StringIO to cache data
         fStringIO = StringIO.StringIO('')  
         
         for Item in VfrUniOffsetList:
             if (Item[0].find("Strings") != -1):
@@ -1083,20 +1116,13 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 fStringIO.write (VfrValue)
             
         #
         # write data into file.
         #
-        try :  
-            fInputfile.write (fStringIO.getvalue())
+        try :
+            SaveFileOnChange(UniVfrOffsetFileName, fStringIO.getvalue())
         except:
             EdkLogger.error("GenFds", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %UniVfrOffsetFileName,None)
         
         fStringIO.close ()
-        fInputfile.close ()
-        
-                
-                    
-            
-            
-        
-                                
+
         
diff --git a/BaseTools/Source/Python/GenFds/Fv.py b/BaseTools/Source/Python/GenFds/Fv.py
index 4b03adc..bfa78b1 100644
--- a/BaseTools/Source/Python/GenFds/Fv.py
+++ b/BaseTools/Source/Python/GenFds/Fv.py
@@ -20,10 +20,11 @@ import subprocess
 import StringIO
 from struct import *
 
 import Ffs
 import AprioriSection
+import FfsFileStatement
 from GenFdsGlobalVariable import GenFdsGlobalVariable
 from GenFds import GenFds
 from CommonDataClass.FdfClass import FvClassObject
 from Common.Misc import SaveFileOnChange
 from Common.LongFilePathSupport import CopyLongFilePath
@@ -64,11 +65,11 @@ class FV (FvClassObject):
     #   @param  ErasePolarity      Flash erase polarity
     #   @param  VtfDict     VTF objects
     #   @param  MacroDict   macro value pair
     #   @retval string      Generated FV file path
     #
-    def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}) :
+    def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}, Flag=False) :
 
         if BaseAddress == None and self.UiFvName.upper() + 'fv' in GenFds.ImageBinDict.keys():
             return GenFds.ImageBinDict[self.UiFvName.upper() + 'fv']
         
         #
@@ -85,135 +86,143 @@ class FV (FvClassObject):
                                 continue
                             elif RegionData.upper() + 'fv' in GenFds.ImageBinDict.keys():
                                 continue
                             elif self.UiFvName.upper() == RegionData.upper():
                                 GenFdsGlobalVariable.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self.CapsuleName, self.UiFvName.upper()))
-
-        GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName)
+        if not Flag:
+            GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName)
         GenFdsGlobalVariable.LargeFileInFvFlags.append(False)
         FFSGuid = None
         
         if self.FvBaseAddress != None:
             BaseAddress = self.FvBaseAddress
-
-        self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict)
+        if not Flag:
+            self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict)
         #
         # First Process the Apriori section
         #
         MacroDict.update(self.DefineVarDict)
 
         GenFdsGlobalVariable.VerboseLogger('First generate Apriori file !')
         FfsFileList = []
         for AprSection in self.AprioriSectionList:
-            FileName = AprSection.GenFfs (self.UiFvName, MacroDict)
+            FileName = AprSection.GenFfs (self.UiFvName, MacroDict, IsMakefile=Flag)
             FfsFileList.append(FileName)
             # Add Apriori file name to Inf file
-            self.FvInfFile.writelines("EFI_FILE_NAME = " + \
-                                       FileName          + \
-                                           T_CHAR_LF)
+            if not Flag:
+                self.FvInfFile.writelines("EFI_FILE_NAME = " + \
+                                            FileName          + \
+                                            T_CHAR_LF)
 
         # Process Modules in FfsList
         for FfsFile in self.FfsList :
-            FileName = FfsFile.GenFfs(MacroDict, FvParentAddr=BaseAddress)
+            if Flag:
+                if isinstance(FfsFile, FfsFileStatement.FileStatement):
+                    continue
+            FileName = FfsFile.GenFfs(MacroDict, FvParentAddr=BaseAddress, IsMakefile=Flag)
             FfsFileList.append(FileName)
-            self.FvInfFile.writelines("EFI_FILE_NAME = " + \
-                                       FileName          + \
-                                       T_CHAR_LF)
-
-        SaveFileOnChange(self.InfFileName, self.FvInfFile.getvalue(), False)
-        self.FvInfFile.close()
+            if not Flag:
+                self.FvInfFile.writelines("EFI_FILE_NAME = " + \
+                                            FileName          + \
+                                            T_CHAR_LF)
+        if not Flag:
+            SaveFileOnChange(self.InfFileName, self.FvInfFile.getvalue(), False)
+            self.FvInfFile.close()
         #
         # Call GenFv tool
         #
         FvOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName)
         FvOutputFile = FvOutputFile + '.Fv'
         # BUGBUG: FvOutputFile could be specified from FDF file (FV section, CreateFile statement)
         if self.CreateFileName != None:
             FvOutputFile = self.CreateFileName
 
+        if Flag:
+            GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile
+            return FvOutputFile
+
         FvInfoFileName = os.path.join(GenFdsGlobalVariable.FfsDir, self.UiFvName + '.inf')
-        CopyLongFilePath(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName)
-        OrigFvInfo = None
-        if os.path.exists (FvInfoFileName):
-            OrigFvInfo = open(FvInfoFileName, 'r').read()
-        if GenFdsGlobalVariable.LargeFileInFvFlags[-1]:
-            FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID;
-        GenFdsGlobalVariable.GenerateFirmwareVolume(
-                                FvOutputFile,
-                                [self.InfFileName],
-                                AddressFile=FvInfoFileName,
-                                FfsList=FfsFileList,
-                                ForceRebase=self.FvForceRebase,
-                                FileSystemGuid=FFSGuid
-                                )
+        if not Flag:
+            CopyLongFilePath(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName)
+            OrigFvInfo = None
+            if os.path.exists (FvInfoFileName):
+                OrigFvInfo = open(FvInfoFileName, 'r').read()
+            if GenFdsGlobalVariable.LargeFileInFvFlags[-1]:
+                FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID
+            GenFdsGlobalVariable.GenerateFirmwareVolume(
+                                    FvOutputFile,
+                                    [self.InfFileName],
+                                    AddressFile=FvInfoFileName,
+                                    FfsList=FfsFileList,
+                                    ForceRebase=self.FvForceRebase,
+                                    FileSystemGuid=FFSGuid
+                                    )
 
-        NewFvInfo = None
-        if os.path.exists (FvInfoFileName):
-            NewFvInfo = open(FvInfoFileName, 'r').read()
-        if NewFvInfo != None and NewFvInfo != OrigFvInfo:
-            FvChildAddr = []
-            AddFileObj = open(FvInfoFileName, 'r')
-            AddrStrings = AddFileObj.readlines()
-            AddrKeyFound = False
-            for AddrString in AddrStrings:
-                if AddrKeyFound:
-                    #get base address for the inside FvImage
-                    FvChildAddr.append (AddrString)
-                elif AddrString.find ("[FV_BASE_ADDRESS]") != -1:
-                    AddrKeyFound = True
-            AddFileObj.close()
+            NewFvInfo = None
+            if os.path.exists (FvInfoFileName):
+                NewFvInfo = open(FvInfoFileName, 'r').read()
+            if NewFvInfo != None and NewFvInfo != OrigFvInfo:
+                FvChildAddr = []
+                AddFileObj = open(FvInfoFileName, 'r')
+                AddrStrings = AddFileObj.readlines()
+                AddrKeyFound = False
+                for AddrString in AddrStrings:
+                    if AddrKeyFound:
+                        #get base address for the inside FvImage
+                        FvChildAddr.append (AddrString)
+                    elif AddrString.find ("[FV_BASE_ADDRESS]") != -1:
+                        AddrKeyFound = True
+                AddFileObj.close()
 
-            if FvChildAddr != []:
-                # Update Ffs again
-                for FfsFile in self.FfsList :
-                    FileName = FfsFile.GenFfs(MacroDict, FvChildAddr, BaseAddress)
-                
-                if GenFdsGlobalVariable.LargeFileInFvFlags[-1]:
-                    FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID;
-                #Update GenFv again
-                GenFdsGlobalVariable.GenerateFirmwareVolume(
-                                        FvOutputFile,
-                                        [self.InfFileName],
-                                        AddressFile=FvInfoFileName,
-                                        FfsList=FfsFileList,
-                                        ForceRebase=self.FvForceRebase,
-                                        FileSystemGuid=FFSGuid
-                                        )
+                if FvChildAddr != []:
+                    # Update Ffs again
+                    for FfsFile in self.FfsList :
+                        FileName = FfsFile.GenFfs(MacroDict, FvChildAddr, BaseAddress, IsMakefile=Flag)
 
-        #
-        # Write the Fv contents to Buffer
-        #
-        if os.path.isfile(FvOutputFile):
-            FvFileObj = open ( FvOutputFile,'rb')
+                    if GenFdsGlobalVariable.LargeFileInFvFlags[-1]:
+                        FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID;
+                    #Update GenFv again
+                        GenFdsGlobalVariable.GenerateFirmwareVolume(
+                                                FvOutputFile,
+                                                [self.InfFileName],
+                                                AddressFile=FvInfoFileName,
+                                                FfsList=FfsFileList,
+                                                ForceRebase=self.FvForceRebase,
+                                                FileSystemGuid=FFSGuid
+                                                )
 
-            GenFdsGlobalVariable.VerboseLogger( "\nGenerate %s FV Successfully" %self.UiFvName)
-            GenFdsGlobalVariable.SharpCounter = 0
+            #
+            # Write the Fv contents to Buffer
+            #
+            if os.path.isfile(FvOutputFile):
+                FvFileObj = open(FvOutputFile, 'rb')
+                GenFdsGlobalVariable.VerboseLogger("\nGenerate %s FV Successfully" % self.UiFvName)
+                GenFdsGlobalVariable.SharpCounter = 0
 
-            Buffer.write(FvFileObj.read())
-            FvFileObj.seek(0)
-            # PI FvHeader is 0x48 byte
-            FvHeaderBuffer = FvFileObj.read(0x48)
-            # FV alignment position.
-            FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F)
-            # FvAlignmentValue is larger than or equal to 1K
-            if FvAlignmentValue >= 0x400:
-                if FvAlignmentValue >= 0x100000:
-                    #The max alignment supported by FFS is 16M.
-                    if FvAlignmentValue >= 0x1000000:
-                        self.FvAlignment = "16M"
+                Buffer.write(FvFileObj.read())
+                FvFileObj.seek(0)
+                # PI FvHeader is 0x48 byte
+                FvHeaderBuffer = FvFileObj.read(0x48)
+                # FV alignment position.
+                FvAlignmentValue = 1 << (ord(FvHeaderBuffer[0x2E]) & 0x1F)
+                if FvAlignmentValue >= 0x400:
+                    if FvAlignmentValue >= 0x100000:
+                        if FvAlignmentValue >= 0x1000000:
+                        #The max alignment supported by FFS is 16M.
+                            self.FvAlignment = "16M"
+                        else:
+                            self.FvAlignment = str(FvAlignmentValue / 0x100000) + "M"
                     else:
-                        self.FvAlignment = str(FvAlignmentValue / 0x100000) + "M"
+                        self.FvAlignment = str(FvAlignmentValue / 0x400) + "K"
                 else:
-                    self.FvAlignment = str (FvAlignmentValue / 0x400) + "K"
+                    # FvAlignmentValue is less than 1K
+                    self.FvAlignment = str (FvAlignmentValue)
+                FvFileObj.close()
+                GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile
+                GenFdsGlobalVariable.LargeFileInFvFlags.pop()
             else:
-                # FvAlignmentValue is less than 1K
-                self.FvAlignment = str (FvAlignmentValue)
-            FvFileObj.close()
-            GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile
-            GenFdsGlobalVariable.LargeFileInFvFlags.pop()
-        else:
-            GenFdsGlobalVariable.ErrorLogger("Failed to generate %s FV file." %self.UiFvName)
+                GenFdsGlobalVariable.ErrorLogger("Failed to generate %s FV file." %self.UiFvName)
         return FvOutputFile
 
     ## _GetBlockSize()
     #
     #   Calculate FV's block size
diff --git a/BaseTools/Source/Python/GenFds/FvImageSection.py b/BaseTools/Source/Python/GenFds/FvImageSection.py
index 68f17c3..916ff91 100644
--- a/BaseTools/Source/Python/GenFds/FvImageSection.py
+++ b/BaseTools/Source/Python/GenFds/FvImageSection.py
@@ -48,11 +48,11 @@ class FvImageSection(FvImageSectionClassObject):
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}, IsMakefile = False):
 
         OutputFileList = []
         if self.FvFileType != None:
             FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FvFileType, self.FvFileExtension)
             if IsSect :
@@ -73,11 +73,11 @@ class FvImageSection(FvImageSectionClassObject):
                     FvFileObj.close()
                 if FvAlignmentValue > MaxFvAlignment:
                     MaxFvAlignment = FvAlignmentValue
 
                 OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get("FV_IMAGE"))
-                GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE')
+                GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile)
                 OutputFileList.append(OutputFile)
 
             # MaxFvAlignment is larger than or equal to 1K
             if MaxFvAlignment >= 0x400:
                 if MaxFvAlignment >= 0x100000:
@@ -99,11 +99,11 @@ class FvImageSection(FvImageSectionClassObject):
         if self.FvName != None:
             Buffer = StringIO.StringIO('')
             Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName)
             if Fv != None:
                 self.Fv = Fv
-                FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict = Dict)
+                FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict = Dict, Flag=IsMakefile)
                 if Fv.FvAlignment != None:
                     if self.Alignment == None:
                         self.Alignment = Fv.FvAlignment
                     else:
                         if GenFdsGlobalVariable.GetAlignment (Fv.FvAlignment) > GenFdsGlobalVariable.GetAlignment (self.Alignment):
@@ -137,9 +137,9 @@ class FvImageSection(FvImageSectionClassObject):
 
             #
             # Prepare the parameter of GenSection
             #
             OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get("FV_IMAGE"))
-            GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE')
+            GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile)
             OutputFileList.append(OutputFile)
 
             return OutputFileList, self.Alignment
diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py
index 277da35..bedfaac 100644
--- a/BaseTools/Source/Python/GenFds/GenFds.py
+++ b/BaseTools/Source/Python/GenFds/GenFds.py
@@ -606,10 +606,27 @@ class GenFds :
             if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:
                 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")
                 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():
                     OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]
                     OptRomObj.AddToBuffer(None)
+    @staticmethod
+    def GenFfsMakefile(OutputDir, FdfParser, WorkSpace, ArchList, GlobalData):
+        GenFdsGlobalVariable.SetEnv(FdfParser, WorkSpace, ArchList, GlobalData)
+        for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
+            FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]
+            FdObj.GenFd(Flag=True)
+
+        for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
+            FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]
+            FvObj.AddToBuffer(Buffer=None, Flag=True)
+
+        if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:
+            for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():
+                OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]
+                OptRomObj.AddToBuffer(Buffer=None, Flag=True)
+
+        return GenFdsGlobalVariable.FfsCmdDict
 
     ## GetFvBlockSize()
     #
     #   @param  FvObj           Whose block size to get
     #   @retval int             Block size value
diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
index 83996be..1d7e78f 100644
--- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
+++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
@@ -67,10 +67,13 @@ class GenFdsGlobalVariable:
     
     BuildRuleFamily = "MSFT"
     ToolChainFamily = "MSFT"
     __BuildRuleDatabase = None
     GuidToolDefinition = {}
+    FfsCmdDict = {}
+    SecCmdList = []
+    CopyList   = []
     
     #
     # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.
     # At the beginning of each generation of FV, false flag is appended to the list,
     # after the call to GenerateSection returns, check the size of the output file,
@@ -262,10 +265,14 @@ class GenFdsGlobalVariable:
     
                 RuleChain.append(FileType)
                 SourceList.extend(Target.Outputs)
                 LastTarget = Target
                 FileType = DataType.TAB_UNKNOWN_FILE
+                for Cmd in Target.Commands:
+                    if "$(CP)" == Cmd.split()[0]:
+                        CpTarget = Cmd.split()[2]
+                        TargetList.add(CpTarget)
 
         return list(TargetList)
 
     ## SetDir()
     #
@@ -315,10 +322,75 @@ class GenFdsGlobalVariable:
                                        RtAddress + \
                                        T_CHAR_LF)
 
         FvAddressFile.close()
 
+    def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData):
+        GenFdsGlobalVariable.FdfParser = FdfParser
+        GenFdsGlobalVariable.WorkSpace = WorkSpace
+        GenFdsGlobalVariable.ArchList = ArchList
+        GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]
+        GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"]
+        GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform
+        GenFdsGlobalVariable.EdkSourceDir = GlobalData.gGlobalDefines["EDK_SOURCE"]
+        GenFdsGlobalVariable.ConfDir  = GlobalData.gConfDirectory
+        for Arch in ArchList:
+            GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath(
+                os.path.join(GlobalData.gWorkspace,
+                             WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,GlobalData.gGlobalDefines['TARGET'],
+                             GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory,
+                             GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN']))
+            GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath(
+                             WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
+                             GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory)
+            GenFdsGlobalVariable.PlatformName = WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
+                                                                      GlobalData.gGlobalDefines['TARGET'],
+                                                                      GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName
+        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)
+
+        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:
+            BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
+                                                                   GlobalData.gGlobalDefines['TARGET'],
+                                                                   GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress
+            if BsAddress:
+                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, GlobalData.gGlobalDefines['TARGET'],
+                GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress:
+                RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[
+                    GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],
+                    GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].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):
@@ -361,11 +433,11 @@ class GenFdsGlobalVariable:
                 return True
         return False
 
     @staticmethod
     def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
-                        GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None):
+                        GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None, IsMakefile=False):
         Cmd = ["GenSec"]
         if Type not in [None, '']:
             Cmd += ["-s", Type]
         if CompressionType not in [None, '']:
             Cmd += ["-c", CompressionType]
@@ -383,40 +455,53 @@ class GenFdsGlobalVariable:
                 Cmd += ["--sectionalign", SecAlign]
 
         CommandFile = Output + '.txt'
         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())
+            if IsMakefile:
+                Cmd += ["-n", "$(MODULE_NAME)"]
+                Cmd += ["-o", Output]
+                #SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
+                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
+                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
+            else:
+                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 += ["-n", Ver]
             if BuildNumber:
                 Cmd += ["-j", BuildNumber]
             Cmd += ["-o", Output]
 
             SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
-            if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
-                return
-
-            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
+            if IsMakefile:
+                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
+                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
+            else:
+                if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
+                    return
+                GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
         else:
             Cmd += ["-o", Output]
             Cmd += Input
 
             SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
-            if GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
+            if IsMakefile:
+                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
+                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
+            elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input)):
                 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
                 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
-
-            if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and
-                GenFdsGlobalVariable.LargeFileInFvFlags):
-                GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True 
+                if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and
+                    GenFdsGlobalVariable.LargeFileInFvFlags):
+                    GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True
 
     @staticmethod
     def GetAlignment (AlignString):
         if AlignString == None:
             return 0
@@ -427,11 +512,11 @@ class GenFdsGlobalVariable:
         else:
             return int (AlignString)
 
     @staticmethod
     def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
-                    SectionAlign=None):
+                    SectionAlign=None, MakefilePath=None):
         Cmd = ["GenFfs", "-t", Type, "-g", Guid]
         mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]
         if Fixed == True:
             Cmd += ["-x"]
         if CheckSum:
@@ -451,15 +536,21 @@ class GenFdsGlobalVariable:
             if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']:
                 Cmd += ("-n", SectionAlign[I])
 
         CommandFile = Output + '.txt'
         SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
-            return
-        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
 
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")
+        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
+        if MakefilePath:
+            if (tuple(Cmd),tuple(GenFdsGlobalVariable.SecCmdList),tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict.keys():
+                GenFdsGlobalVariable.FfsCmdDict[tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)] = MakefilePath
+                GenFdsGlobalVariable.SecCmdList = []
+                GenFdsGlobalVariable.CopyList = []
+        else:
+            if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input)):
+                return
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")
 
     @staticmethod
     def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,
                                AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None):
         if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):
@@ -509,12 +600,12 @@ class GenFdsGlobalVariable:
         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):
+                              Align=None, Padding=None, Convert=False, IsMakefile=False):
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
             return
         GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
 
         Cmd = ["GenFw"]
         if Type.lower() == "te":
@@ -537,16 +628,19 @@ class GenFdsGlobalVariable:
             Cmd += ["-j"]
         if Convert:
             Cmd += ["-m"]
         Cmd += ["-o", Output]
         Cmd += Input
-
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")
+        if IsMakefile:
+            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
+                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
+        else:
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")
 
     @staticmethod
     def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,
-                        Revision=None, DeviceId=None, VendorId=None):
+                        Revision=None, DeviceId=None, VendorId=None, IsMakefile=False):
         InputList = []   
         Cmd = ["EfiRom"]
         if len(EfiInput) > 0:
             
             if Compress:
@@ -563,11 +657,11 @@ class GenFdsGlobalVariable:
             for BinFile in BinaryInput:
                 Cmd += [BinFile]
                 InputList.append (BinFile)
 
         # Check List
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList):
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList) and not IsMakefile:
             return
         GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))
                         
         if ClassCode != None:
             Cmd += ["-l", ClassCode]
@@ -577,24 +671,31 @@ class GenFdsGlobalVariable:
             Cmd += ["-i", DeviceId]
         if VendorId != None:
             Cmd += ["-f", VendorId]
 
         Cmd += ["-o", Output]
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")
+        if IsMakefile:
+            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
+                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
+        else:
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")
 
     @staticmethod
-    def GuidTool(Output, Input, ToolPath, Options='', returnValue=[]):
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
+    def GuidTool(Output, Input, ToolPath, Options='', returnValue=[], IsMakefile=False):
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
             return
         GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
 
         Cmd = [ToolPath, ]
         Cmd += Options.split(' ')
         Cmd += ["-o", Output]
         Cmd += Input
-
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)
+        if IsMakefile:
+            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
+                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
+        else:
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)
 
     def CallExternalTool (cmd, errorMess, returnValue=[]):
 
         if type(cmd) not in (tuple, list):
             GenFdsGlobalVariable.ErrorLogger("ToolError!  Invalid parameter type in call to CallExternalTool")
@@ -725,10 +826,11 @@ class GenFdsGlobalVariable:
                         return PcdValue
 
         return PcdValue
 
     SetDir = staticmethod(SetDir)
+    SetEnv = staticmethod(SetEnv)
     ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro)
     CallExternalTool = staticmethod(CallExternalTool)
     VerboseLogger = staticmethod(VerboseLogger)
     InfLogger = staticmethod(InfLogger)
     ErrorLogger = staticmethod(ErrorLogger)
diff --git a/BaseTools/Source/Python/GenFds/GuidSection.py b/BaseTools/Source/Python/GenFds/GuidSection.py
index f199dcd..4eb149a 100644
--- a/BaseTools/Source/Python/GenFds/GuidSection.py
+++ b/BaseTools/Source/Python/GenFds/GuidSection.py
@@ -1,9 +1,9 @@
 ## @file
 # process GUIDed section generation
 #
-#  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -52,11 +52,11 @@ class GuidSection(GuidSectionClassObject) :
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile=False):
         #
         # Generate all section
         #
         self.KeyStringList = KeyStringList
         self.CurrentArchList = GenFdsGlobalVariable.ArchList
@@ -92,11 +92,11 @@ class GuidSection(GuidSectionClassObject) :
                     Sect.FvAddr = self.FvAddr.pop(0)
                 self.IncludeFvSection = True
             elif isinstance(Sect, GuidSection):
                 Sect.FvAddr = self.FvAddr
                 Sect.FvParentAddr = self.FvParentAddr
-            ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict)
+            ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile)
             if isinstance(Sect, GuidSection):
                 if Sect.IncludeFvSection:
                     self.IncludeFvSection = Sect.IncludeFvSection
 
             if align != None:
@@ -135,11 +135,11 @@ class GuidSection(GuidSectionClassObject) :
         # If not have GUID , call default
         # GENCRC32 section
         #
         if self.NameGuid == None :
             GenFdsGlobalVariable.VerboseLogger("Use GenSection function Generate CRC32 Section")
-            GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign)
+            GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign, IsMakefile=IsMakefile)
             OutputFileList = []
             OutputFileList.append(OutputFile)
             return OutputFileList, self.Alignment
         #or GUID not in External Tool List
         elif ExternalTool == None:
@@ -147,11 +147,11 @@ class GuidSection(GuidSectionClassObject) :
         else:
             DummyFile = OutputFile + ".dummy"
             #
             # Call GenSection with DUMMY section type.
             #
-            GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign)
+            GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign, IsMakefile=IsMakefile)
             #
             # Use external tool process the Output
             #
             TempFile = OutputPath + \
                        os.sep + \
@@ -170,79 +170,36 @@ class GuidSection(GuidSectionClassObject) :
 
             FirstCall = False
             CmdOption = '-e'
             if ExternalOption != None:
                 CmdOption = CmdOption + ' ' + ExternalOption
-            if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr != None:
-                #FirstCall is only set for the encapsulated flash FV image without process required attribute.
-                FirstCall = True
-            #
-            # Call external tool
-            #
-            ReturnValue = [1]
-            if FirstCall:
-                #first try to call the guided tool with -z option and CmdOption for the no process required guided tool.
-                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue)
 
-            #
-            # when no call or first call failed, ReturnValue are not 1.
-            # Call the guided tool with CmdOption
-            #
-            if ReturnValue[0] != 0:
-                FirstCall = False
-                ReturnValue[0] = 0
-                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
+            GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption, IsMakefile=IsMakefile)
             #
             # There is external tool which does not follow standard rule which return nonzero if tool fails
             # The output file has to be checked
             #
-            if not os.path.exists(TempFile):
+            if not IsMakefile and not os.path.exists(TempFile):
                 EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool)
 
-            FileHandleIn = open(DummyFile, 'rb')
-            FileHandleIn.seek(0, 2)
-            InputFileSize = FileHandleIn.tell()
-
-            FileHandleOut = open(TempFile, 'rb')
-            FileHandleOut.seek(0, 2)
-            TempFileSize = FileHandleOut.tell()
 
             Attribute = []
             HeaderLength = None
             if self.ExtraHeaderSize != -1:
                 HeaderLength = str(self.ExtraHeaderSize)
 
-            if self.ProcessRequired == "NONE" and HeaderLength == None:
-                if TempFileSize > InputFileSize:
-                    FileHandleIn.seek(0)
-                    BufferIn = FileHandleIn.read()
-                    FileHandleOut.seek(0)
-                    BufferOut = FileHandleOut.read()
-                    if BufferIn == BufferOut[TempFileSize - InputFileSize:]:
-                        HeaderLength = str(TempFileSize - InputFileSize)
-                #auto sec guided attribute with process required
-                if HeaderLength == None:
-                    Attribute.append('PROCESSING_REQUIRED')
-
-            FileHandleIn.close()
-            FileHandleOut.close()
-
-            if FirstCall and 'PROCESSING_REQUIRED' in Attribute:
-                # Guided data by -z option on first call is the process required data. Call the guided tool with the real option.
-                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
-
             #
             # Call Gensection Add Section Header
             #
             if self.ProcessRequired in ("TRUE", "1"):
                 if 'PROCESSING_REQUIRED' not in Attribute:
                     Attribute.append('PROCESSING_REQUIRED')
 
             if self.AuthStatusValid in ("TRUE", "1"):
                 Attribute.append('AUTH_STATUS_VALID')
             GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
-                                                 Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength)
+                                                 Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength, IsMakefile=IsMakefile)
             OutputFileList = []
             OutputFileList.append(OutputFile)
             if 'PROCESSING_REQUIRED' in Attribute:
                 # reset guided section alignment to none for the processed required guided data
                 self.Alignment = None
diff --git a/BaseTools/Source/Python/GenFds/OptRomFileStatement.py b/BaseTools/Source/Python/GenFds/OptRomFileStatement.py
index 5e3273d..ab4fae6 100644
--- a/BaseTools/Source/Python/GenFds/OptRomFileStatement.py
+++ b/BaseTools/Source/Python/GenFds/OptRomFileStatement.py
@@ -1,9 +1,9 @@
 ## @file
 # process OptionROM generation from FILE statement
 #
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -37,11 +37,11 @@ class OptRomFileStatement:
     #
     #   @param  self        The object pointer
     #   @param  Dict        dictionary contains macro and value pair
     #   @retval string      Generated FFS file name
     #
-    def GenFfs(self, Dict = {}):
+    def GenFfs(self, Dict = {}, IsMakefile=False):
         
         if self.FileName != None:
             self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
         
         return self.FileName
diff --git a/BaseTools/Source/Python/GenFds/OptRomInfStatement.py b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py
index 069414d..80c4bba 100644
--- a/BaseTools/Source/Python/GenFds/OptRomInfStatement.py
+++ b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py
@@ -1,9 +1,9 @@
 ## @file
 # process OptionROM generation from INF statement
 #
-#  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -79,11 +79,11 @@ class OptRomInfStatement (FfsInfStatement):
     #   Generate FFS
     #
     #   @param  self        The object pointer
     #   @retval string      Generated .efi file name
     #
-    def GenFfs(self):
+    def GenFfs(self, IsMakefile=False):
         #
         # Parse Inf file get Module related information
         #
 
         self.__InfParse__()
@@ -96,28 +96,28 @@ class OptRomInfStatement (FfsInfStatement):
         #FileType = Ffs.Ffs.ModuleTypeToFileType[Rule.ModuleType]
         #
         # For the rule only has simpleFile
         #
         if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :
-            EfiOutputList = self.__GenSimpleFileSection__(Rule)
+            EfiOutputList = self.__GenSimpleFileSection__(Rule, IsMakefile=IsMakefile)
             return EfiOutputList
         #
         # For Rule has ComplexFile
         #
         elif isinstance(Rule, RuleComplexFile.RuleComplexFile):
-            EfiOutputList = self.__GenComplexFileSection__(Rule)
+            EfiOutputList = self.__GenComplexFileSection__(Rule, IsMakefile=IsMakefile)
             return EfiOutputList
 
     ## __GenSimpleFileSection__() method
     #
     #   Get .efi files according to simple rule.
     #
     #   @param  self        The object pointer
     #   @param  Rule        The rule object used to generate section
     #   @retval string      File name of the generated section file
     #
-    def __GenSimpleFileSection__(self, Rule):
+    def __GenSimpleFileSection__(self, Rule, IsMakefile = False):
         #
         # Prepare the parameter of GenSection
         #
 
         OutputFileList = []
@@ -136,11 +136,11 @@ class OptRomInfStatement (FfsInfStatement):
     #
     #   @param  self        The object pointer
     #   @param  Rule        The rule object used to generate section
     #   @retval string      File name of the generated section file
     #
-    def __GenComplexFileSection__(self, Rule):
+    def __GenComplexFileSection__(self, Rule, IsMakefile=False):
 
         OutputFileList = []
         for Sect in Rule.SectionList:
             if Sect.SectionType == 'PE32':
                 if Sect.FileName != None:
diff --git a/BaseTools/Source/Python/GenFds/OptionRom.py b/BaseTools/Source/Python/GenFds/OptionRom.py
index 7886a7c..2e61a38 100644
--- a/BaseTools/Source/Python/GenFds/OptionRom.py
+++ b/BaseTools/Source/Python/GenFds/OptionRom.py
@@ -1,9 +1,9 @@
 ## @file
 # process OptionROM generation
 #
-#  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -47,22 +47,22 @@ class OPTIONROM (OptionRomClassObject):
     #
     #   @param  self        The object pointer
     #   @param  Buffer      The buffer generated OptROM data will be put
     #   @retval string      Generated OptROM file path
     #
-    def AddToBuffer (self, Buffer) :
-
-        GenFdsGlobalVariable.InfLogger( "\nGenerating %s Option ROM ..." %self.DriverName)
+    def AddToBuffer (self, Buffer, Flag=False) :
+        if not Flag:
+            GenFdsGlobalVariable.InfLogger( "\nGenerating %s Option ROM ..." %self.DriverName)
 
         EfiFileList = []
         BinFileList = []
 
         # Process Modules in FfsList
         for FfsFile in self.FfsList :
             
             if isinstance(FfsFile, OptRomInfStatement.OptRomInfStatement):
-                FilePathNameList = FfsFile.GenFfs()
+                FilePathNameList = FfsFile.GenFfs(IsMakefile=Flag)
                 if len(FilePathNameList) == 0:
                     EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s not produce .efi files, so NO file could be put into option ROM." % (FfsFile.InfFileName))
                 if FfsFile.OverrideAttribs == None:
                     EfiFileList.extend(FilePathNameList)
                 else:
@@ -77,14 +77,15 @@ class OPTIONROM (OptionRomClassObject):
                                                            [], 
                                                            FfsFile.OverrideAttribs.NeedCompress, 
                                                            FfsFile.OverrideAttribs.PciClassCode, 
                                                            FfsFile.OverrideAttribs.PciRevision, 
                                                            FfsFile.OverrideAttribs.PciDeviceId, 
-                                                           FfsFile.OverrideAttribs.PciVendorId)
+                                                           FfsFile.OverrideAttribs.PciVendorId,
+                                                           IsMakefile = Flag)
                     BinFileList.append(TmpOutputFile)
             else:
-                FilePathName = FfsFile.GenFfs()
+                FilePathName = FfsFile.GenFfs(IsMakefile=Flag)
                 if FfsFile.OverrideAttribs != None:
                     FileName = os.path.basename(FilePathName)
                     TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName, FfsFile.CurrentArch)
                     if not os.path.exists(TmpOutputDir) :
                         os.makedirs(TmpOutputDir)
@@ -95,11 +96,12 @@ class OPTIONROM (OptionRomClassObject):
                                                            [], 
                                                            FfsFile.OverrideAttribs.NeedCompress, 
                                                            FfsFile.OverrideAttribs.PciClassCode, 
                                                            FfsFile.OverrideAttribs.PciRevision, 
                                                            FfsFile.OverrideAttribs.PciDeviceId, 
-                                                           FfsFile.OverrideAttribs.PciVendorId)
+                                                           FfsFile.OverrideAttribs.PciVendorId,
+                                                           IsMakefile=Flag)
                     BinFileList.append(TmpOutputFile)
                 else:
                     if FfsFile.FileType == 'EFI':
                         EfiFileList.append(FilePathName)
                     else:
@@ -112,14 +114,15 @@ class OPTIONROM (OptionRomClassObject):
         OutputFile = OutputFile + '.rom'
         
         GenFdsGlobalVariable.GenerateOptionRom(
                                 OutputFile,
                                 EfiFileList,
-                                BinFileList
-                                )
+                                BinFileList,
+                                IsMakefile=Flag)
 
-        GenFdsGlobalVariable.InfLogger( "\nGenerate %s Option ROM Successfully" %self.DriverName)
+        if not Flag:
+            GenFdsGlobalVariable.InfLogger( "\nGenerate %s Option ROM Successfully" %self.DriverName)
         GenFdsGlobalVariable.SharpCounter = 0
         
         return OutputFile
 
 class OverrideAttribs:
diff --git a/BaseTools/Source/Python/GenFds/Region.py b/BaseTools/Source/Python/GenFds/Region.py
index 945c548..c946758 100644
--- a/BaseTools/Source/Python/GenFds/Region.py
+++ b/BaseTools/Source/Python/GenFds/Region.py
@@ -1,9 +1,9 @@
 ## @file
 # process FD Region generation
 #
-#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -72,15 +72,18 @@ class Region(RegionClassObject):
     #   @param  VtfDict     VTF objects
     #   @param  MacroDict   macro value pair
     #   @retval string      Generated FV file path
     #
 
-    def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, ImageBinDict, vtfDict=None, MacroDict={}):
+    def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, ImageBinDict, vtfDict=None, MacroDict={}, Flag=False):
         Size = self.Size
-        GenFdsGlobalVariable.InfLogger('\nGenerate Region at Offset 0x%X' % self.Offset)
-        GenFdsGlobalVariable.InfLogger("   Region Size = 0x%X" % Size)
+        if not Flag:
+            GenFdsGlobalVariable.InfLogger('\nGenerate Region at Offset 0x%X' % self.Offset)
+            GenFdsGlobalVariable.InfLogger("   Region Size = 0x%X" % Size)
         GenFdsGlobalVariable.SharpCounter = 0
+        if Flag and (self.RegionType != 'FV'):
+            return
 
         if self.RegionType == 'FV':
             #
             # Get Fv from FvDict
             #
@@ -89,30 +92,33 @@ class Region(RegionClassObject):
             FvOffset = 0
             for RegionData in self.RegionDataList:
                 FileName = None
                 if RegionData.endswith(".fv"):
                     RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
-                    GenFdsGlobalVariable.InfLogger('   Region FV File Name = .fv : %s' % RegionData)
+                    if not Flag:
+                        GenFdsGlobalVariable.InfLogger('   Region FV File Name = .fv : %s' % RegionData)
                     if RegionData[1] != ':' :
                         RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
                     if not os.path.exists(RegionData):
                         EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
 
                     FileName = RegionData
                 elif RegionData.upper() + 'fv' in ImageBinDict.keys():
-                    GenFdsGlobalVariable.InfLogger('   Region Name = FV')
+                    if not Flag:
+                        GenFdsGlobalVariable.InfLogger('   Region Name = FV')
                     FileName = ImageBinDict[RegionData.upper() + 'fv']
                 else:
                     #
                     # Generate FvImage.
                     #
                     FvObj = None
                     if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
                         FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper())
 
                     if FvObj != None :
-                        GenFdsGlobalVariable.InfLogger('   Region Name = FV')
+                        if not Flag:
+                            GenFdsGlobalVariable.InfLogger('   Region Name = FV')
                         #
                         # Call GenFv tool
                         #
                         self.BlockInfoOfRegion(BlockSizeList, FvObj)
                         self.FvAddress = self.FvAddress + FvOffset
@@ -122,11 +128,14 @@ class Region(RegionClassObject):
                                             "FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment))
                         FvBuffer = StringIO.StringIO('')
                         FvBaseAddress = '0x%X' % self.FvAddress
                         BlockSize = None
                         BlockNum = None
-                        FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict)
+                        FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict, Flag=Flag)
+                        if Flag:
+                            continue
+
                         if FvBuffer.len > Size:
                             FvBuffer.close()
                             EdkLogger.error("GenFds", GENFDS_ERROR,
                                             "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData, Size))
                         #
@@ -140,24 +149,26 @@ class Region(RegionClassObject):
                     else:
                         EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (RegionData))
                 #
                 # Add the exist Fv image into FD buffer
                 #
-                if FileName != None:
-                    FileLength = os.stat(FileName)[ST_SIZE]
-                    if FileLength > Size:
-                        EdkLogger.error("GenFds", GENFDS_ERROR,
-                                        "Size of FV File (%s) is larger than Region Size 0x%X specified." \
-                                        % (RegionData, Size))
-                    BinFile = open(FileName, 'rb')
-                    Buffer.write(BinFile.read())
-                    BinFile.close()
-                    Size = Size - FileLength
+                if not Flag:
+                    if FileName != None:
+                        FileLength = os.stat(FileName)[ST_SIZE]
+                        if FileLength > Size:
+                            EdkLogger.error("GenFds", GENFDS_ERROR,
+                                            "Size of FV File (%s) is larger than Region Size 0x%X specified." \
+                                            % (RegionData, Size))
+                        BinFile = open(FileName, 'rb')
+                        Buffer.write(BinFile.read())
+                        BinFile.close()
+                        Size = Size - FileLength
             #
             # Pad the left buffer
             #
-            self.PadBuffer(Buffer, ErasePolarity, Size)
+            if not Flag:
+                self.PadBuffer(Buffer, ErasePolarity, Size)
 
         if self.RegionType == 'CAPSULE':
             #
             # Get Capsule from Capsule Dict
             #
diff --git a/BaseTools/Source/Python/GenFds/Section.py b/BaseTools/Source/Python/GenFds/Section.py
index 942dd5c..4c1aaac 100644
--- a/BaseTools/Source/Python/GenFds/Section.py
+++ b/BaseTools/Source/Python/GenFds/Section.py
@@ -1,9 +1,9 @@
 ## @file
 # section base class
 #
-#  Copyright (c) 2007-2015, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007-2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -139,11 +139,11 @@ class Section (SectionClassObject):
                     else:
                         GenFdsGlobalVariable.VerboseLogger ("\nFile Type \'%s\' of File %s in %s is not same with file type \'%s\' from Rule in FDF" %(File.Type, File.File, FfsInf.InfFileName, FileType))
                 else:
                     GenFdsGlobalVariable.InfLogger ("\nCurrent ARCH \'%s\' of File %s is not in the Support Arch Scope of %s specified by INF %s in FDF" %(FfsInf.CurrentArch, File.File, File.Arch, FfsInf.InfFileName))
 
-        if Suffix != None and os.path.exists(FfsInf.EfiOutputPath):
+        if Suffix != None:
             #
             # Get Makefile path and time stamp
             #
             MakefileDir = FfsInf.EfiOutputPath[:-len('OUTPUT')]
             Makefile = os.path.join(MakefileDir, 'Makefile')
diff --git a/BaseTools/Source/Python/GenFds/UiSection.py b/BaseTools/Source/Python/GenFds/UiSection.py
index 419e1ee..4f6926f 100644
--- a/BaseTools/Source/Python/GenFds/UiSection.py
+++ b/BaseTools/Source/Python/GenFds/UiSection.py
@@ -46,11 +46,11 @@ class UiSection (UiSectionClassObject):
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile = False):
         #
         # Prepare the parameter of GenSection
         #
         if FfsInf != None:
             self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
@@ -67,11 +67,10 @@ class UiSection (UiSectionClassObject):
             FileObj = open(FileNameStr, 'r')
             NameString = FileObj.read()
             FileObj.close()
         else:
             NameString = ''
-
-        GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_USER_INTERFACE', Ui=NameString)
+        GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_USER_INTERFACE', Ui=NameString, IsMakefile=IsMakefile)
 
         OutputFileList = []
         OutputFileList.append(OutputFile)
         return OutputFileList, self.Alignment
diff --git a/BaseTools/Source/Python/GenFds/VerSection.py b/BaseTools/Source/Python/GenFds/VerSection.py
index ad995d3..e290299 100644
--- a/BaseTools/Source/Python/GenFds/VerSection.py
+++ b/BaseTools/Source/Python/GenFds/VerSection.py
@@ -1,9 +1,9 @@
 ## @file
 # process Version section generation
 #
-#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -46,11 +46,11 @@ class VerSection (VerSectionClassObject):
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile = False):
         #
         # Prepare the parameter of GenSection
         #
         if FfsInf != None:
             self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
@@ -63,21 +63,20 @@ class VerSection (VerSectionClassObject):
         OutputFile = os.path.normpath(OutputFile)
 
         # Get String Data
         StringData = ''
         if self.StringData != None:
-             StringData = self.StringData
+            StringData = self.StringData
         elif self.FileName != None:
             FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
             FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict)
             FileObj = open(FileNameStr, 'r')
             StringData = FileObj.read()
             StringData = '"' + StringData + '"'
             FileObj.close()
         else:
             StringData = ''
-
         GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
-                                             Ver=StringData, BuildNumber=self.BuildNum)
+                                             Ver=StringData, BuildNumber=self.BuildNum, IsMakefile=IsMakefile)
         OutputFileList = []
         OutputFileList.append(OutputFile)
         return OutputFileList, self.Alignment
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index 13d8e50..cb6c732 100644
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -48,10 +48,11 @@ from BuildReport import BuildReport
 from GenPatchPcdTable.GenPatchPcdTable import *
 from PatchPcdValue.PatchPcdValue import *
 
 import Common.EdkLogger
 import Common.GlobalData as GlobalData
+from GenFds.GenFds import GenFds
 
 # Version and Copyright
 VersionNumber = "0.60" + ' ' + gBUILD_VERSION
 __version__ = "%prog Version " + VersionNumber
 __copyright__ = "Copyright (c) 2007 - 2017, Intel Corporation  All rights reserved."
@@ -1960,10 +1961,21 @@ class Build():
                 self.Fdf = Wa.FdfFile
                 self.LoadFixAddress = Wa.Platform.LoadFixAddress
                 self.BuildReport.AddPlatformReport(Wa)
                 Wa.CreateMakeFile(False)
 
+                # Add ffs build to makefile
+                CmdListDict = {}
+                if self.Fdf:
+                    GenFfsDict = GenFds.GenFfsMakefile('', GlobalData.gFdfParser, self.Db, self.ArchList, GlobalData)
+                    for Cmd in GenFfsDict:
+                        tmpInf, tmpArch = GenFfsDict[Cmd]
+                        if (tmpInf, tmpArch) not in CmdListDict.keys():
+                            CmdListDict[tmpInf, tmpArch] = [Cmd]
+                        else:
+                            CmdListDict[tmpInf, tmpArch].append(Cmd)
+
                 # multi-thread exit flag
                 ExitFlag = threading.Event()
                 ExitFlag.clear()
                 self.AutoGenTime += int(round((time.time() - WorkspaceAutoGenTime)))
                 for Arch in Wa.ArchList:
@@ -1998,11 +2010,15 @@ class Build():
                                 Ma.CreateCodeFile(True)
                             if self.Target == "genc":
                                 continue
 
                             if not self.SkipAutoGen or self.Target == 'genmake':
-                                Ma.CreateMakeFile(True)
+                                if CmdListDict and self.Fdf and (Module.File, Arch) in CmdListDict:
+                                    Ma.CreateMakeFile(True, CmdListDict[Module.File, Arch])
+                                    del CmdListDict[Module.File, Arch]
+                                else:
+                                    Ma.CreateMakeFile(True)
                             if self.Target == "genmake":
                                 continue
                         self.BuildModules.append(Ma)
                     self.Progress.Stop("done!")
                     self.AutoGenTime += int(round((time.time() - AutoGenStart)))
-- 
2.6.1.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel