]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools: Add support to merge Prebuild and Postbuild into build Process
authorYonghong Zhu <yonghong.zhu@intel.com>
Thu, 31 Mar 2016 06:05:59 +0000 (14:05 +0800)
committerYonghong Zhu <yonghong.zhu@intel.com>
Thu, 7 Apr 2016 05:13:22 +0000 (13:13 +0800)
This feature is enhance build tool to incorporate execution of prebuild
and postbuild.

1.Prebuild script
a.DEFINE PREBUILD in DSC [Defines] section
b.Build command -D PREBUILD to override the one in DSC [Defines] section
1)If PREBUILD is a file, then this file will be used as prebuild script.
2)If PREBUILD is empty, then prebuild script will be disabled.
3)If PREBUILD is not defined in [Defines] section and not passed in on
command line, then prebuild script is also disabled.

2.Prebuild option
a.All options of build tool
b.TARGET, ARCH and TOOL_CHAIN_TAG value, Those value will be from
target.txt file if they are not in build command line.
c.Additional options following prebuild definition. Quotes are needed
when these additional options are present.
d.Quotes would also be required if the path to the prebuild command
contains space or special characters.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
BaseTools/Source/Python/Common/BuildToolError.py
BaseTools/Source/Python/Common/DataType.py
BaseTools/Source/Python/Common/DscClassObject.py
BaseTools/Source/Python/Common/GlobalData.py
BaseTools/Source/Python/CommonDataClass/PlatformClass.py
BaseTools/Source/Python/Workspace/MetaFileParser.py
BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
BaseTools/Source/Python/build/build.py

index 0a393fec60ca724f475a9fdf13a20c1df07768c4..bee5850fc5ab071fa36788ff335392695da12177 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Standardized Error Hanlding infrastructures.\r
 #\r
 ## @file\r
 # Standardized Error Hanlding infrastructures.\r
 #\r
-# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -78,6 +78,8 @@ BUILD_ERROR = 0xF002
 GENFDS_ERROR = 0xF003\r
 ECC_ERROR = 0xF004\r
 EOT_ERROR = 0xF005\r
 GENFDS_ERROR = 0xF003\r
 ECC_ERROR = 0xF004\r
 EOT_ERROR = 0xF005\r
+PREBUILD_ERROR = 0xF007\r
+POSTBUILD_ERROR = 0xF008\r
 DDC_ERROR = 0xF009\r
 WARNING_AS_ERROR = 0xF006\r
 MIGRATION_ERROR = 0xF010\r
 DDC_ERROR = 0xF009\r
 WARNING_AS_ERROR = 0xF006\r
 MIGRATION_ERROR = 0xF010\r
index 4fd46edab96d69fe044a7ba837571d8341e242c5..1fe1ee458b9d1b43039be0653ea63ebd1740e686 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to define common static strings used by INF/DEC/DSC files\r
 #\r
 ## @file\r
 # This file is used to define common static strings used by INF/DEC/DSC files\r
 #\r
-# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
 # Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
@@ -410,7 +410,8 @@ TAB_DSC_DEFINES_DEFINE = 'DEFINE'
 TAB_DSC_DEFINES_VPD_TOOL_GUID = 'VPD_TOOL_GUID'\r
 TAB_FIX_LOAD_TOP_MEMORY_ADDRESS = 'FIX_LOAD_TOP_MEMORY_ADDRESS'\r
 TAB_DSC_DEFINES_EDKGLOBAL = 'EDK_GLOBAL'\r
 TAB_DSC_DEFINES_VPD_TOOL_GUID = 'VPD_TOOL_GUID'\r
 TAB_FIX_LOAD_TOP_MEMORY_ADDRESS = 'FIX_LOAD_TOP_MEMORY_ADDRESS'\r
 TAB_DSC_DEFINES_EDKGLOBAL = 'EDK_GLOBAL'\r
-\r
+TAB_DSC_PREBUILD = 'PREBUILD'\r
+TAB_DSC_POSTBUILD = 'POSTBUILD'\r
 #\r
 # TargetTxt Definitions\r
 #\r
 #\r
 # TargetTxt Definitions\r
 #\r
index 788a75e26777397465a8ac6f88ac758b21bc6591..c2fa1c275a2d99a774e28a432307f602d114df96 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to define each component of DSC file\r
 #\r
 ## @file\r
 # This file is used to define each component of DSC file\r
 #\r
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -98,11 +98,10 @@ class Dsc(DscObject):
         self.UserExtensions = ''\r
         self.WorkspaceDir = WorkspaceDir\r
         self.IsToDatabase = IsToDatabase\r
         self.UserExtensions = ''\r
         self.WorkspaceDir = WorkspaceDir\r
         self.IsToDatabase = IsToDatabase\r
-\r
-        self.Cur = Database.Cur\r
-        self.TblFile = Database.TblFile\r
-        self.TblDsc = Database.TblDsc\r
-\r
+        if Database:\r
+            self.Cur = Database.Cur\r
+            self.TblFile = Database.TblFile\r
+            self.TblDsc = Database.TblDsc\r
 \r
         self.KeyList = [\r
             TAB_SKUIDS, TAB_LIBRARIES, TAB_LIBRARY_CLASSES, TAB_BUILD_OPTIONS, TAB_PCDS_FIXED_AT_BUILD_NULL, \\r
 \r
         self.KeyList = [\r
             TAB_SKUIDS, TAB_LIBRARIES, TAB_LIBRARY_CLASSES, TAB_BUILD_OPTIONS, TAB_PCDS_FIXED_AT_BUILD_NULL, \\r
@@ -252,6 +251,12 @@ class Dsc(DscObject):
             Fdf = PlatformFlashDefinitionFileClass()\r
             Fdf.FilePath = NormPath(QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_FLASH_DEFINITION, Arch, self.FileID)[0])\r
             self.Platform.FlashDefinitionFile = Fdf\r
             Fdf = PlatformFlashDefinitionFileClass()\r
             Fdf.FilePath = NormPath(QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_FLASH_DEFINITION, Arch, self.FileID)[0])\r
             self.Platform.FlashDefinitionFile = Fdf\r
+            Prebuild = BuildScriptClass()\r
+            Prebuild.FilePath = NormPath(QueryDefinesItem(self.TblDsc, TAB_DSC_PREBUILD, Arch, self.FileID)[0])\r
+            self.Platform.Prebuild = Prebuild\r
+            Postbuild = BuildScriptClass()\r
+            Postbuild.FilePath = NormPath(QueryDefinesItem(self.TblDsc, TAB_DSC_POSTBUILD, Arch, self.FileID)[0])\r
+            self.Platform.Postbuild = Postbuild\r
 \r
     ## GenBuildOptions\r
     #\r
 \r
     ## GenBuildOptions\r
     #\r
index c3439ebbfcf589cbcf70e1ad9a49b76999d44008..51e370925dc09d14b5cb8e46aef28ac7aedec098 100644 (file)
@@ -23,6 +23,7 @@ gEcpSource = "EdkCompatibilityPkg"
 gOptions = None\r
 gCaseInsensitive = False\r
 gAllFiles = None\r
 gOptions = None\r
 gCaseInsensitive = False\r
 gAllFiles = None\r
+gCommand = None\r
 \r
 gGlobalDefines = {}\r
 gPlatformDefines = {}\r
 \r
 gGlobalDefines = {}\r
 gPlatformDefines = {}\r
index a95ec068b1cb34ac52fbb0d50a109b1cc7ea6fc7..a93d1ce2a1dbf187f3423319d1b6aa66524d2418 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to define a class object to describe a platform\r
 #\r
 ## @file\r
 # This file is used to define a class object to describe a platform\r
 #\r
-# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.    The full text of the license may be found at\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.    The full text of the license may be found at\r
@@ -86,6 +86,24 @@ class PlatformFlashDefinitionFileClass(object):
         self.Preferred = False\r
         self.FilePath = ''\r
 \r
         self.Preferred = False\r
         self.FilePath = ''\r
 \r
+## BuildScriptClass\r
+#\r
+# This class defined PREBUILD/POSTBUILD item used in platform file\r
+#\r
+# @param object:   Inherited from object class\r
+#\r
+# @var Id:         To store value for Id\r
+# @var UiName:     To store value for UiName\r
+# @var Preferred:  To store value for Preferred\r
+# @var FilePath:   To store value for FilePath\r
+#\r
+class BuildScriptClass(object):\r
+    def __init__(self):\r
+        self.Id = ''\r
+        self.UiName = ''\r
+        self.Preferred = False\r
+        self.FilePath = ''\r
+\r
 ## PlatformFvImageOptionClass\r
 #\r
 # This class defined FvImageOption item used in platform file\r
 ## PlatformFvImageOptionClass\r
 #\r
 # This class defined FvImageOption item used in platform file\r
@@ -401,6 +419,10 @@ class PlatformModuleClasses(IncludeStatementClass):
 #                                   PlatformModuleClasses\r
 # @var FlashDefinitionFile:         To store value for FlashDefinitionFile, it is a structure as\r
 #                                   PlatformFlashDefinitionFileClass\r
 #                                   PlatformModuleClasses\r
 # @var FlashDefinitionFile:         To store value for FlashDefinitionFile, it is a structure as\r
 #                                   PlatformFlashDefinitionFileClass\r
+# @var Prebuild:                    To store value for PREBUILD, it is a structure as\r
+#                                   BuildScriptClass\r
+# @var Postbuild:                   To store value for POSTBUILD, it is a structure as\r
+#                                   BuildScriptClass\r
 # @var BuildOptions:                To store value for BuildOptions, it is a structure as\r
 #                                   PlatformBuildOptionClasses\r
 # @var DynamicPcdBuildDefinitions:  To store value for DynamicPcdBuildDefinitions, it is a list structure as\r
 # @var BuildOptions:                To store value for BuildOptions, it is a structure as\r
 #                                   PlatformBuildOptionClasses\r
 # @var DynamicPcdBuildDefinitions:  To store value for DynamicPcdBuildDefinitions, it is a list structure as\r
@@ -418,6 +440,8 @@ class PlatformClass(object):
         self.LibraryClasses = PlatformLibraryClasses()\r
         self.Modules = PlatformModuleClasses()\r
         self.FlashDefinitionFile = PlatformFlashDefinitionFileClass()\r
         self.LibraryClasses = PlatformLibraryClasses()\r
         self.Modules = PlatformModuleClasses()\r
         self.FlashDefinitionFile = PlatformFlashDefinitionFileClass()\r
+        self.Prebuild = BuildScriptClass()\r
+        self.Postbuild = BuildScriptClass()\r
         self.BuildOptions = PlatformBuildOptionClasses()\r
         self.DynamicPcdBuildDefinitions = []\r
         self.Fdf = []\r
         self.BuildOptions = PlatformBuildOptionClasses()\r
         self.DynamicPcdBuildDefinitions = []\r
         self.Fdf = []\r
index 451d8547d22b3ffcc132de96b930f4114ebaf6a4..3b6a3c0dfa5cf2a25162bcb99bb5d4946449f81a 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to parse meta files\r
 #\r
 ## @file\r
 # This file is used to parse meta files\r
 #\r
-# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>\r
 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
@@ -831,7 +831,9 @@ class DscParser(MetaFileParser):
         "ISO_LANGUAGES",\r
         "TIME_STAMP_FILE",\r
         "VPD_TOOL_GUID",\r
         "ISO_LANGUAGES",\r
         "TIME_STAMP_FILE",\r
         "VPD_TOOL_GUID",\r
-        "FIX_LOAD_TOP_MEMORY_ADDRESS"\r
+        "FIX_LOAD_TOP_MEMORY_ADDRESS",\r
+        "PREBUILD",\r
+        "POSTBUILD"\r
     ]\r
 \r
     SubSectionDefineKeywords = [\r
     ]\r
 \r
     SubSectionDefineKeywords = [\r
index 1f236e83ff5120028adf58442dd026f479b4df4e..b2c4d6e4dafbf7657b2ef202eaebb0b9adbdc3f1 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to create a database used by build tool\r
 #\r
 ## @file\r
 # This file is used to create a database used by build tool\r
 #\r
-# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -137,6 +137,8 @@ class DscBuildData(PlatformBuildClassObject):
         self._PcdInfoFlag       = None\r
         self._VarCheckFlag = None\r
         self._FlashDefinition   = None\r
         self._PcdInfoFlag       = None\r
         self._VarCheckFlag = None\r
         self._FlashDefinition   = None\r
+        self._Prebuild          = None\r
+        self._Postbuild         = None\r
         self._BuildNumber       = None\r
         self._MakefileName      = None\r
         self._BsBaseAddress     = None\r
         self._BuildNumber       = None\r
         self._MakefileName      = None\r
         self._BsBaseAddress     = None\r
@@ -227,6 +229,10 @@ class DscBuildData(PlatformBuildClassObject):
                 if ErrorCode != 0:\r
                     EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],\r
                                     ExtraData=ErrorInfo)\r
                 if ErrorCode != 0:\r
                     EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],\r
                                     ExtraData=ErrorInfo)\r
+            elif Name == TAB_DSC_PREBUILD:\r
+                self._Prebuild = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r
+            elif Name == TAB_DSC_POSTBUILD:\r
+                self._Postbuild = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r
             elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r
                 self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
             elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
             elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r
                 self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
             elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
@@ -399,6 +405,22 @@ class DscBuildData(PlatformBuildClassObject):
                 self._FlashDefinition = ''\r
         return self._FlashDefinition\r
 \r
                 self._FlashDefinition = ''\r
         return self._FlashDefinition\r
 \r
+    def _GetPrebuild(self):\r
+        if self._Prebuild == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._Prebuild == None:\r
+                self._Prebuild = ''\r
+        return self._Prebuild\r
+\r
+    def _GetPostbuild(self):\r
+        if self._Postbuild == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._Postbuild == None:\r
+                self._Postbuild = ''\r
+        return self._Postbuild\r
+\r
     ## Retrieve FLASH_DEFINITION\r
     def _GetBuildNumber(self):\r
         if self._BuildNumber == None:\r
     ## Retrieve FLASH_DEFINITION\r
     def _GetBuildNumber(self):\r
         if self._BuildNumber == None:\r
@@ -1207,6 +1229,8 @@ class DscBuildData(PlatformBuildClassObject):
     PcdInfoFlag         = property(_GetPcdInfoFlag)\r
     VarCheckFlag = property(_GetVarCheckFlag)\r
     FlashDefinition     = property(_GetFdfFile)\r
     PcdInfoFlag         = property(_GetPcdInfoFlag)\r
     VarCheckFlag = property(_GetVarCheckFlag)\r
     FlashDefinition     = property(_GetFdfFile)\r
+    Prebuild            = property(_GetPrebuild)\r
+    Postbuild           = property(_GetPostbuild)\r
     BuildNumber         = property(_GetBuildNumber)\r
     MakefileName        = property(_GetMakefileName)\r
     BsBaseAddress       = property(_GetBsBaseAddress)\r
     BuildNumber         = property(_GetBuildNumber)\r
     MakefileName        = property(_GetMakefileName)\r
     BsBaseAddress       = property(_GetBsBaseAddress)\r
@@ -2979,6 +3003,13 @@ determine whether database file is out of date!\n")
                 PlatformList.append(Platform)\r
         return PlatformList\r
 \r
                 PlatformList.append(Platform)\r
         return PlatformList\r
 \r
+    def _MapPlatform(self, Dscfile):\r
+        try:\r
+            Platform = self.BuildObject[PathClass(Dscfile), 'COMMON']\r
+        except:\r
+            Platform = None\r
+        return Platform\r
+\r
     PlatformList = property(_GetPlatformList)\r
 \r
 ##\r
     PlatformList = property(_GetPlatformList)\r
 \r
 ##\r
index ece79ea1092a80b7df1070682b449f02515e4944..37afe52ac298858627170c545b77fcba28242c80 100644 (file)
@@ -25,6 +25,7 @@ import time
 import platform\r
 import traceback\r
 import encodings.ascii\r
 import platform\r
 import traceback\r
 import encodings.ascii\r
+import itertools\r
 \r
 from struct import *\r
 from threading import *\r
 \r
 from struct import *\r
 from threading import *\r
@@ -782,15 +783,16 @@ class Build():
         self.LoadFixAddress = 0\r
         self.UniFlag        = BuildOptions.Flag\r
         self.BuildModules = []\r
         self.LoadFixAddress = 0\r
         self.UniFlag        = BuildOptions.Flag\r
         self.BuildModules = []\r
-\r
+        self.Db_Flag = False\r
+        self.LaunchPrebuildFlag = False\r
+        self.PrebuildScript = ''\r
+        self.PostbuildScript = ''\r
+        self.PlatformBuildPath = os.path.join(GlobalData.gConfDirectory,'.cache', '.PlatformBuild')\r
         if BuildOptions.CommandLength:\r
             GlobalData.gCommandMaxLength = BuildOptions.CommandLength\r
 \r
         # print dot character during doing some time-consuming work\r
         self.Progress = Utils.Progressor()\r
         if BuildOptions.CommandLength:\r
             GlobalData.gCommandMaxLength = BuildOptions.CommandLength\r
 \r
         # print dot character during doing some time-consuming work\r
         self.Progress = Utils.Progressor()\r
-\r
-        self.InitBuild()\r
-\r
         # print current build environment and configuration\r
         EdkLogger.quiet("%-16s = %s" % ("WORKSPACE", os.environ["WORKSPACE"]))\r
         if "PACKAGES_PATH" in os.environ:\r
         # print current build environment and configuration\r
         EdkLogger.quiet("%-16s = %s" % ("WORKSPACE", os.environ["WORKSPACE"]))\r
         if "PACKAGES_PATH" in os.environ:\r
@@ -804,8 +806,18 @@ class Build():
             # Print the same path style with WORKSPACE env. \r
             EdkLogger.quiet("%-16s = %s" % ("EDK_TOOLS_BIN", os.path.normcase(os.path.normpath(os.environ["EDK_TOOLS_BIN"]))))\r
 \r
             # Print the same path style with WORKSPACE env. \r
             EdkLogger.quiet("%-16s = %s" % ("EDK_TOOLS_BIN", os.path.normcase(os.path.normpath(os.environ["EDK_TOOLS_BIN"]))))\r
 \r
-        EdkLogger.info("")\r
+        self.InitPreBuild()\r
+        self.InitPostBuild()\r
+        if self.PrebuildScript:\r
+            EdkLogger.quiet("%-16s = %s" % ("PREBUILD", self.PrebuildScript))\r
+        if self.PostbuildScript:\r
+            EdkLogger.quiet("%-16s = %s" % ("POSTBUILD", self.PostbuildScript))\r
+        if self.PrebuildScript:\r
+            self.LaunchPrebuild()\r
+        if not (self.LaunchPrebuildFlag and os.path.exists(self.PlatformBuildPath)):\r
+            self.InitBuild()\r
 \r
 \r
+        EdkLogger.info("")\r
         os.chdir(self.WorkspaceDir)\r
 \r
     ## Load configuration\r
         os.chdir(self.WorkspaceDir)\r
 \r
     ## Load configuration\r
@@ -903,8 +915,169 @@ class Build():
             EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo)\r
 \r
         # create metafile database\r
             EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo)\r
 \r
         # create metafile database\r
-        self.Db.InitDatabase()\r
+        if not self.Db_Flag:\r
+            self.Db.InitDatabase()\r
+\r
+    def InitPreBuild(self):\r
+        self.LoadConfiguration()\r
+        if self.BuildTargetList:\r
+            GlobalData.gGlobalDefines['TARGET'] = self.BuildTargetList[0]\r
+        if self.ArchList:\r
+            GlobalData.gGlobalDefines['ARCH'] = self.ArchList[0]\r
+        if self.ToolChainList:\r
+            GlobalData.gGlobalDefines['TOOLCHAIN'] = self.ToolChainList[0]\r
+            GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = self.ToolChainList[0]\r
+        if 'PREBUILD' in GlobalData.gCommandLineDefines.keys():\r
+            self.Prebuild   = GlobalData.gCommandLineDefines.get('PREBUILD')\r
+        else:\r
+            self.Db.InitDatabase()\r
+            self.Db_Flag = True\r
+            Platform = self.Db._MapPlatform(str(self.PlatformFile))\r
+            self.Prebuild = str(Platform.Prebuild)\r
+        if self.Prebuild:\r
+            PrebuildList = self.Prebuild.split()\r
+            if not os.path.isabs(PrebuildList[0]):\r
+                PrebuildList[0] = mws.join(self.WorkspaceDir, PrebuildList[0])\r
+            if os.path.isfile(PrebuildList[0]):\r
+                self.PrebuildScript = PrebuildList[0]\r
+                self.Prebuild = ' '.join(PrebuildList)\r
+                self.Prebuild += self.PassCommandOption(self.BuildTargetList, self.ArchList, self.ToolChainList)\r
+                #self.LaunchPrebuild()\r
+            else:\r
+                EdkLogger.error("Prebuild", PREBUILD_ERROR, "the prebuild script %s is not exist.\n If you'd like to disable the Prebuild process, please use the format: -D PREBUILD=\"\" " %(PrebuildList[0]))\r
 \r
 \r
+    def InitPostBuild(self):\r
+        if 'POSTBUILD' in GlobalData.gCommandLineDefines.keys():\r
+            self.Postbuild = GlobalData.gCommandLineDefines.get('POSTBUILD')\r
+        else:\r
+            Platform = self.Db._MapPlatform(str(self.PlatformFile))\r
+            self.Postbuild = str(Platform.Postbuild)\r
+        if self.Postbuild:\r
+            PostbuildList = self.Postbuild.split()\r
+            if not os.path.isabs(PostbuildList[0]):\r
+                PostbuildList[0] = mws.join(self.WorkspaceDir, PostbuildList[0])\r
+            if os.path.isfile(PostbuildList[0]):\r
+                self.PostbuildScript = PostbuildList[0]\r
+                self.Postbuild = ' '.join(PostbuildList)\r
+                self.Postbuild += self.PassCommandOption(self.BuildTargetList, self.ArchList, self.ToolChainList)\r
+                #self.LanuchPostbuild()\r
+            else:\r
+                EdkLogger.error("Postbuild", POSTBUILD_ERROR, "the postbuild script %s is not exist.\n If you'd like to disable the Postbuild process, please use the format: -D POSTBUILD=\"\" " %(PostbuildList[0]))\r
+\r
+    def PassCommandOption(self, BuildTarget, TargetArch, ToolChain):\r
+        BuildStr = ''\r
+        if GlobalData.gCommand and isinstance(GlobalData.gCommand, list):\r
+            BuildStr += ' ' + ' '.join(GlobalData.gCommand)\r
+        TargetFlag = False\r
+        ArchFlag = False\r
+        ToolChainFlag = False\r
+\r
+        if GlobalData.gOptions and not GlobalData.gOptions.BuildTarget:\r
+            TargetFlag = True\r
+        if GlobalData.gOptions and not GlobalData.gOptions.TargetArch:\r
+            ArchFlag = True\r
+        if GlobalData.gOptions and not GlobalData.gOptions.ToolChain:\r
+            ToolChainFlag = True\r
+\r
+        if TargetFlag and BuildTarget:\r
+            if isinstance(BuildTarget, list) or isinstance(BuildTarget, tuple):\r
+                BuildStr += ' -b ' + ' -b '.join(BuildTarget)\r
+            elif isinstance(BuildTarget, str):\r
+                BuildStr += ' -b ' + BuildTarget\r
+        if ArchFlag and TargetArch:\r
+            if isinstance(TargetArch, list) or isinstance(TargetArch, tuple):\r
+                BuildStr += ' -a ' + ' -a '.join(TargetArch)\r
+            elif isinstance(TargetArch, str):\r
+                BuildStr += ' -a ' + TargetArch\r
+        if ToolChainFlag and ToolChain:\r
+            if isinstance(ToolChain, list) or isinstance(ToolChain, tuple):\r
+                BuildStr += ' -t ' + ' -t '.join(ToolChain)\r
+            elif isinstance(ToolChain, str):\r
+                BuildStr += ' -t ' + ToolChain\r
+\r
+        return BuildStr\r
+\r
+    def LaunchPrebuild(self):\r
+        if self.Prebuild:\r
+            EdkLogger.info("\n- Prebuild Start -\n")\r
+            self.LaunchPrebuildFlag = True\r
+            PrebuildEnvFile = os.path.join(GlobalData.gConfDirectory,'.cache','.PrebuildEnv')\r
+            if os.path.isfile(PrebuildEnvFile):\r
+                os.remove(PrebuildEnvFile)\r
+            if os.path.isfile(self.PlatformBuildPath):\r
+                os.remove(self.PlatformBuildPath)\r
+            if sys.platform == "win32":\r
+                args = ' && '.join((self.Prebuild, 'set > ' + PrebuildEnvFile))\r
+                Process = Popen(args, stdout=PIPE, stderr=PIPE)\r
+            else:\r
+                args = ' && '.join((self.Prebuild, 'env > ' + PrebuildEnvFile))\r
+                Process = Popen(args, stdout=PIPE, stderr=PIPE, shell=True, executable="/bin/bash")\r
+\r
+            # launch two threads to read the STDOUT and STDERR\r
+            EndOfProcedure = Event()\r
+            EndOfProcedure.clear()\r
+            if Process.stdout:\r
+                StdOutThread = Thread(target=ReadMessage, args=(Process.stdout, EdkLogger.info, EndOfProcedure))\r
+                StdOutThread.setName("STDOUT-Redirector")\r
+                StdOutThread.setDaemon(False)\r
+                StdOutThread.start()\r
+\r
+            if Process.stderr:\r
+                StdErrThread = Thread(target=ReadMessage, args=(Process.stderr, EdkLogger.quiet, EndOfProcedure))\r
+                StdErrThread.setName("STDERR-Redirector")\r
+                StdErrThread.setDaemon(False)\r
+                StdErrThread.start()\r
+            # waiting for program exit\r
+            Process.wait()\r
+\r
+            if Process.stdout:\r
+                StdOutThread.join()\r
+            if Process.stderr:\r
+                StdErrThread.join()\r
+            if Process.returncode != 0 :\r
+                EdkLogger.error("Prebuild", PREBUILD_ERROR, 'Prebuild process is not success!')\r
+\r
+            if os.path.exists(PrebuildEnvFile):\r
+                f = open(PrebuildEnvFile)\r
+                envs = f.readlines()\r
+                f.close()\r
+                envs = itertools.imap(lambda l: l.split('=',1), envs)\r
+                envs = itertools.ifilter(lambda l: len(l) == 2, envs)\r
+                envs = itertools.imap(lambda l: [i.strip() for i in l], envs)\r
+                os.environ.update(dict(envs))\r
+            EdkLogger.info("\n- Prebuild Done -\n")\r
+\r
+    def LanuchPostbuild(self):\r
+        if self.Postbuild:\r
+            EdkLogger.info("\n- Postbuild Start -\n")\r
+            if sys.platform == "win32":\r
+                Process = Popen(self.Postbuild, stdout=PIPE, stderr=PIPE)\r
+            else:\r
+                Process = Popen(self.Postbuild, stdout=PIPE, stderr=PIPE, shell=True, executable="/bin/bash")\r
+            # launch two threads to read the STDOUT and STDERR\r
+            EndOfProcedure = Event()\r
+            EndOfProcedure.clear()\r
+            if Process.stdout:\r
+                StdOutThread = Thread(target=ReadMessage, args=(Process.stdout, EdkLogger.info, EndOfProcedure))\r
+                StdOutThread.setName("STDOUT-Redirector")\r
+                StdOutThread.setDaemon(False)\r
+                StdOutThread.start()\r
+\r
+            if Process.stderr:\r
+                StdErrThread = Thread(target=ReadMessage, args=(Process.stderr, EdkLogger.quiet, EndOfProcedure))\r
+                StdErrThread.setName("STDERR-Redirector")\r
+                StdErrThread.setDaemon(False)\r
+                StdErrThread.start()\r
+            # waiting for program exit\r
+            Process.wait()\r
+\r
+            if Process.stdout:\r
+                StdOutThread.join()\r
+            if Process.stderr:\r
+                StdErrThread.join()\r
+            if Process.returncode != 0 :\r
+                EdkLogger.error("Postbuild", POSTBUILD_ERROR, 'Postbuild process is not success!')\r
+            EdkLogger.info("\n- Postbuild Done -\n")\r
     ## Build a module or platform\r
     #\r
     # Create autogen code and makefile for a module or platform, and the launch\r
     ## Build a module or platform\r
     #\r
     # Create autogen code and makefile for a module or platform, and the launch\r
@@ -1414,6 +1587,7 @@ class Build():
     ## Build active platform for different build targets and different tool chains\r
     #\r
     def _BuildPlatform(self):\r
     ## Build active platform for different build targets and different tool chains\r
     #\r
     def _BuildPlatform(self):\r
+        SaveFileOnChange(self.PlatformBuildPath, '# DO NOT EDIT \n# FILE auto-generated\n', False)\r
         for BuildTarget in self.BuildTargetList:\r
             GlobalData.gGlobalDefines['TARGET'] = BuildTarget\r
             for ToolChain in self.ToolChainList:\r
         for BuildTarget in self.BuildTargetList:\r
             GlobalData.gGlobalDefines['TARGET'] = BuildTarget\r
             for ToolChain in self.ToolChainList:\r
@@ -1587,6 +1761,7 @@ class Build():
     ## Build a platform in multi-thread mode\r
     #\r
     def _MultiThreadBuildPlatform(self):\r
     ## Build a platform in multi-thread mode\r
     #\r
     def _MultiThreadBuildPlatform(self):\r
+        SaveFileOnChange(self.PlatformBuildPath, '# DO NOT EDIT \n# FILE auto-generated\n', False)\r
         for BuildTarget in self.BuildTargetList:\r
             GlobalData.gGlobalDefines['TARGET'] = BuildTarget\r
             for ToolChain in self.ToolChainList:\r
         for BuildTarget in self.BuildTargetList:\r
             GlobalData.gGlobalDefines['TARGET'] = BuildTarget\r
             for ToolChain in self.ToolChainList:\r
@@ -1961,7 +2136,7 @@ def Main():
 \r
     # Initialize log system\r
     EdkLogger.Initialize()\r
 \r
     # Initialize log system\r
     EdkLogger.Initialize()\r
-\r
+    GlobalData.gCommand = sys.argv[1:]\r
     #\r
     # Parse the options and args\r
     #\r
     #\r
     # Parse the options and args\r
     #\r
@@ -2059,7 +2234,8 @@ def Main():
 \r
         MyBuild = Build(Target, Workspace, Option)\r
         GlobalData.gCommandLineDefines['ARCH'] = ' '.join(MyBuild.ArchList)\r
 \r
         MyBuild = Build(Target, Workspace, Option)\r
         GlobalData.gCommandLineDefines['ARCH'] = ' '.join(MyBuild.ArchList)\r
-        MyBuild.Launch()\r
+        if not (MyBuild.LaunchPrebuildFlag and os.path.exists(MyBuild.PlatformBuildPath)):\r
+            MyBuild.Launch()\r
         # Drop temp tables to avoid database locked.\r
         for TmpTableName in TmpTableDict:\r
             SqlCommand = """drop table IF EXISTS %s""" % TmpTableName\r
         # Drop temp tables to avoid database locked.\r
         for TmpTableName in TmpTableDict:\r
             SqlCommand = """drop table IF EXISTS %s""" % TmpTableName\r
@@ -2116,7 +2292,11 @@ def Main():
         Utils.ClearDuplicatedInf()\r
 \r
     if ReturnCode == 0:\r
         Utils.ClearDuplicatedInf()\r
 \r
     if ReturnCode == 0:\r
-        Conclusion = "Done"\r
+        try:\r
+            MyBuild.LanuchPostbuild()\r
+            Conclusion = "Done"\r
+        except:\r
+            Conclusion = "Failed"\r
     elif ReturnCode == ABORT_ERROR:\r
         Conclusion = "Aborted"\r
     else:\r
     elif ReturnCode == ABORT_ERROR:\r
         Conclusion = "Aborted"\r
     else:\r