BaseTools: Add support to merge Prebuild and Postbuild into build Process

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>
This commit is contained in:
Yonghong Zhu 2016-03-31 14:05:59 +08:00
parent d7cd335681
commit f0dc69e61b
8 changed files with 268 additions and 22 deletions

View File

@ -1,7 +1,7 @@
## @file ## @file
# Standardized Error Hanlding infrastructures. # Standardized Error Hanlding infrastructures.
# #
# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # 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 # which accompanies this distribution. The full text of the license may be found at
@ -78,6 +78,8 @@ BUILD_ERROR = 0xF002
GENFDS_ERROR = 0xF003 GENFDS_ERROR = 0xF003
ECC_ERROR = 0xF004 ECC_ERROR = 0xF004
EOT_ERROR = 0xF005 EOT_ERROR = 0xF005
PREBUILD_ERROR = 0xF007
POSTBUILD_ERROR = 0xF008
DDC_ERROR = 0xF009 DDC_ERROR = 0xF009
WARNING_AS_ERROR = 0xF006 WARNING_AS_ERROR = 0xF006
MIGRATION_ERROR = 0xF010 MIGRATION_ERROR = 0xF010

View File

@ -1,7 +1,7 @@
## @file ## @file
# This file is used to define common static strings used by INF/DEC/DSC files # This file is used to define common static strings used by INF/DEC/DSC files
# #
# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR> # Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
@ -410,7 +410,8 @@ TAB_DSC_DEFINES_DEFINE = 'DEFINE'
TAB_DSC_DEFINES_VPD_TOOL_GUID = 'VPD_TOOL_GUID' TAB_DSC_DEFINES_VPD_TOOL_GUID = 'VPD_TOOL_GUID'
TAB_FIX_LOAD_TOP_MEMORY_ADDRESS = 'FIX_LOAD_TOP_MEMORY_ADDRESS' TAB_FIX_LOAD_TOP_MEMORY_ADDRESS = 'FIX_LOAD_TOP_MEMORY_ADDRESS'
TAB_DSC_DEFINES_EDKGLOBAL = 'EDK_GLOBAL' TAB_DSC_DEFINES_EDKGLOBAL = 'EDK_GLOBAL'
TAB_DSC_PREBUILD = 'PREBUILD'
TAB_DSC_POSTBUILD = 'POSTBUILD'
# #
# TargetTxt Definitions # TargetTxt Definitions
# #

View File

@ -1,7 +1,7 @@
## @file ## @file
# This file is used to define each component of DSC file # This file is used to define each component of DSC file
# #
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # 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 # which accompanies this distribution. The full text of the license may be found at
@ -98,11 +98,10 @@ class Dsc(DscObject):
self.UserExtensions = '' self.UserExtensions = ''
self.WorkspaceDir = WorkspaceDir self.WorkspaceDir = WorkspaceDir
self.IsToDatabase = IsToDatabase self.IsToDatabase = IsToDatabase
if Database:
self.Cur = Database.Cur self.Cur = Database.Cur
self.TblFile = Database.TblFile self.TblFile = Database.TblFile
self.TblDsc = Database.TblDsc self.TblDsc = Database.TblDsc
self.KeyList = [ self.KeyList = [
TAB_SKUIDS, TAB_LIBRARIES, TAB_LIBRARY_CLASSES, TAB_BUILD_OPTIONS, TAB_PCDS_FIXED_AT_BUILD_NULL, \ TAB_SKUIDS, TAB_LIBRARIES, TAB_LIBRARY_CLASSES, TAB_BUILD_OPTIONS, TAB_PCDS_FIXED_AT_BUILD_NULL, \
@ -252,6 +251,12 @@ class Dsc(DscObject):
Fdf = PlatformFlashDefinitionFileClass() Fdf = PlatformFlashDefinitionFileClass()
Fdf.FilePath = NormPath(QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_FLASH_DEFINITION, Arch, self.FileID)[0]) Fdf.FilePath = NormPath(QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_FLASH_DEFINITION, Arch, self.FileID)[0])
self.Platform.FlashDefinitionFile = Fdf self.Platform.FlashDefinitionFile = Fdf
Prebuild = BuildScriptClass()
Prebuild.FilePath = NormPath(QueryDefinesItem(self.TblDsc, TAB_DSC_PREBUILD, Arch, self.FileID)[0])
self.Platform.Prebuild = Prebuild
Postbuild = BuildScriptClass()
Postbuild.FilePath = NormPath(QueryDefinesItem(self.TblDsc, TAB_DSC_POSTBUILD, Arch, self.FileID)[0])
self.Platform.Postbuild = Postbuild
## GenBuildOptions ## GenBuildOptions
# #

View File

@ -23,6 +23,7 @@ gEcpSource = "EdkCompatibilityPkg"
gOptions = None gOptions = None
gCaseInsensitive = False gCaseInsensitive = False
gAllFiles = None gAllFiles = None
gCommand = None
gGlobalDefines = {} gGlobalDefines = {}
gPlatformDefines = {} gPlatformDefines = {}

View File

@ -1,7 +1,7 @@
## @file ## @file
# This file is used to define a class object to describe a platform # This file is used to define a class object to describe a platform
# #
# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # 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 # which accompanies this distribution. The full text of the license may be found at
@ -86,6 +86,24 @@ class PlatformFlashDefinitionFileClass(object):
self.Preferred = False self.Preferred = False
self.FilePath = '' self.FilePath = ''
## BuildScriptClass
#
# This class defined PREBUILD/POSTBUILD item used in platform file
#
# @param object: Inherited from object class
#
# @var Id: To store value for Id
# @var UiName: To store value for UiName
# @var Preferred: To store value for Preferred
# @var FilePath: To store value for FilePath
#
class BuildScriptClass(object):
def __init__(self):
self.Id = ''
self.UiName = ''
self.Preferred = False
self.FilePath = ''
## PlatformFvImageOptionClass ## PlatformFvImageOptionClass
# #
# This class defined FvImageOption item used in platform file # This class defined FvImageOption item used in platform file
@ -401,6 +419,10 @@ class PlatformModuleClasses(IncludeStatementClass):
# PlatformModuleClasses # PlatformModuleClasses
# @var FlashDefinitionFile: To store value for FlashDefinitionFile, it is a structure as # @var FlashDefinitionFile: To store value for FlashDefinitionFile, it is a structure as
# PlatformFlashDefinitionFileClass # PlatformFlashDefinitionFileClass
# @var Prebuild: To store value for PREBUILD, it is a structure as
# BuildScriptClass
# @var Postbuild: To store value for POSTBUILD, it is a structure as
# BuildScriptClass
# @var BuildOptions: To store value for BuildOptions, it is a structure as # @var BuildOptions: To store value for BuildOptions, it is a structure as
# PlatformBuildOptionClasses # PlatformBuildOptionClasses
# @var DynamicPcdBuildDefinitions: To store value for DynamicPcdBuildDefinitions, it is a list structure as # @var DynamicPcdBuildDefinitions: To store value for DynamicPcdBuildDefinitions, it is a list structure as
@ -418,6 +440,8 @@ class PlatformClass(object):
self.LibraryClasses = PlatformLibraryClasses() self.LibraryClasses = PlatformLibraryClasses()
self.Modules = PlatformModuleClasses() self.Modules = PlatformModuleClasses()
self.FlashDefinitionFile = PlatformFlashDefinitionFileClass() self.FlashDefinitionFile = PlatformFlashDefinitionFileClass()
self.Prebuild = BuildScriptClass()
self.Postbuild = BuildScriptClass()
self.BuildOptions = PlatformBuildOptionClasses() self.BuildOptions = PlatformBuildOptionClasses()
self.DynamicPcdBuildDefinitions = [] self.DynamicPcdBuildDefinitions = []
self.Fdf = [] self.Fdf = []

View File

@ -1,7 +1,7 @@
## @file ## @file
# This file is used to parse meta files # This file is used to parse meta files
# #
# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR> # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
@ -831,7 +831,9 @@ class DscParser(MetaFileParser):
"ISO_LANGUAGES", "ISO_LANGUAGES",
"TIME_STAMP_FILE", "TIME_STAMP_FILE",
"VPD_TOOL_GUID", "VPD_TOOL_GUID",
"FIX_LOAD_TOP_MEMORY_ADDRESS" "FIX_LOAD_TOP_MEMORY_ADDRESS",
"PREBUILD",
"POSTBUILD"
] ]
SubSectionDefineKeywords = [ SubSectionDefineKeywords = [

View File

@ -1,7 +1,7 @@
## @file ## @file
# This file is used to create a database used by build tool # This file is used to create a database used by build tool
# #
# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # 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 # which accompanies this distribution. The full text of the license may be found at
@ -137,6 +137,8 @@ class DscBuildData(PlatformBuildClassObject):
self._PcdInfoFlag = None self._PcdInfoFlag = None
self._VarCheckFlag = None self._VarCheckFlag = None
self._FlashDefinition = None self._FlashDefinition = None
self._Prebuild = None
self._Postbuild = None
self._BuildNumber = None self._BuildNumber = None
self._MakefileName = None self._MakefileName = None
self._BsBaseAddress = None self._BsBaseAddress = None
@ -227,6 +229,10 @@ class DscBuildData(PlatformBuildClassObject):
if ErrorCode != 0: if ErrorCode != 0:
EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1], EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],
ExtraData=ErrorInfo) ExtraData=ErrorInfo)
elif Name == TAB_DSC_PREBUILD:
self._Prebuild = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)
elif Name == TAB_DSC_POSTBUILD:
self._Postbuild = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)
elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES: elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:
self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT) self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
elif Name == TAB_DSC_DEFINES_BUILD_TARGETS: elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:
@ -399,6 +405,22 @@ class DscBuildData(PlatformBuildClassObject):
self._FlashDefinition = '' self._FlashDefinition = ''
return self._FlashDefinition return self._FlashDefinition
def _GetPrebuild(self):
if self._Prebuild == None:
if self._Header == None:
self._GetHeaderInfo()
if self._Prebuild == None:
self._Prebuild = ''
return self._Prebuild
def _GetPostbuild(self):
if self._Postbuild == None:
if self._Header == None:
self._GetHeaderInfo()
if self._Postbuild == None:
self._Postbuild = ''
return self._Postbuild
## Retrieve FLASH_DEFINITION ## Retrieve FLASH_DEFINITION
def _GetBuildNumber(self): def _GetBuildNumber(self):
if self._BuildNumber == None: if self._BuildNumber == None:
@ -1207,6 +1229,8 @@ class DscBuildData(PlatformBuildClassObject):
PcdInfoFlag = property(_GetPcdInfoFlag) PcdInfoFlag = property(_GetPcdInfoFlag)
VarCheckFlag = property(_GetVarCheckFlag) VarCheckFlag = property(_GetVarCheckFlag)
FlashDefinition = property(_GetFdfFile) FlashDefinition = property(_GetFdfFile)
Prebuild = property(_GetPrebuild)
Postbuild = property(_GetPostbuild)
BuildNumber = property(_GetBuildNumber) BuildNumber = property(_GetBuildNumber)
MakefileName = property(_GetMakefileName) MakefileName = property(_GetMakefileName)
BsBaseAddress = property(_GetBsBaseAddress) BsBaseAddress = property(_GetBsBaseAddress)
@ -2979,6 +3003,13 @@ determine whether database file is out of date!\n")
PlatformList.append(Platform) PlatformList.append(Platform)
return PlatformList return PlatformList
def _MapPlatform(self, Dscfile):
try:
Platform = self.BuildObject[PathClass(Dscfile), 'COMMON']
except:
Platform = None
return Platform
PlatformList = property(_GetPlatformList) PlatformList = property(_GetPlatformList)
## ##

View File

@ -25,6 +25,7 @@ import time
import platform import platform
import traceback import traceback
import encodings.ascii import encodings.ascii
import itertools
from struct import * from struct import *
from threading import * from threading import *
@ -782,15 +783,16 @@ class Build():
self.LoadFixAddress = 0 self.LoadFixAddress = 0
self.UniFlag = BuildOptions.Flag self.UniFlag = BuildOptions.Flag
self.BuildModules = [] self.BuildModules = []
self.Db_Flag = False
self.LaunchPrebuildFlag = False
self.PrebuildScript = ''
self.PostbuildScript = ''
self.PlatformBuildPath = os.path.join(GlobalData.gConfDirectory,'.cache', '.PlatformBuild')
if BuildOptions.CommandLength: if BuildOptions.CommandLength:
GlobalData.gCommandMaxLength = BuildOptions.CommandLength GlobalData.gCommandMaxLength = BuildOptions.CommandLength
# print dot character during doing some time-consuming work # print dot character during doing some time-consuming work
self.Progress = Utils.Progressor() self.Progress = Utils.Progressor()
self.InitBuild()
# print current build environment and configuration # print current build environment and configuration
EdkLogger.quiet("%-16s = %s" % ("WORKSPACE", os.environ["WORKSPACE"])) EdkLogger.quiet("%-16s = %s" % ("WORKSPACE", os.environ["WORKSPACE"]))
if "PACKAGES_PATH" in os.environ: if "PACKAGES_PATH" in os.environ:
@ -804,8 +806,18 @@ class Build():
# Print the same path style with WORKSPACE env. # Print the same path style with WORKSPACE env.
EdkLogger.quiet("%-16s = %s" % ("EDK_TOOLS_BIN", os.path.normcase(os.path.normpath(os.environ["EDK_TOOLS_BIN"])))) EdkLogger.quiet("%-16s = %s" % ("EDK_TOOLS_BIN", os.path.normcase(os.path.normpath(os.environ["EDK_TOOLS_BIN"]))))
EdkLogger.info("") self.InitPreBuild()
self.InitPostBuild()
if self.PrebuildScript:
EdkLogger.quiet("%-16s = %s" % ("PREBUILD", self.PrebuildScript))
if self.PostbuildScript:
EdkLogger.quiet("%-16s = %s" % ("POSTBUILD", self.PostbuildScript))
if self.PrebuildScript:
self.LaunchPrebuild()
if not (self.LaunchPrebuildFlag and os.path.exists(self.PlatformBuildPath)):
self.InitBuild()
EdkLogger.info("")
os.chdir(self.WorkspaceDir) os.chdir(self.WorkspaceDir)
## Load configuration ## Load configuration
@ -903,8 +915,169 @@ class Build():
EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo) EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo)
# create metafile database # create metafile database
self.Db.InitDatabase() if not self.Db_Flag:
self.Db.InitDatabase()
def InitPreBuild(self):
self.LoadConfiguration()
if self.BuildTargetList:
GlobalData.gGlobalDefines['TARGET'] = self.BuildTargetList[0]
if self.ArchList:
GlobalData.gGlobalDefines['ARCH'] = self.ArchList[0]
if self.ToolChainList:
GlobalData.gGlobalDefines['TOOLCHAIN'] = self.ToolChainList[0]
GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = self.ToolChainList[0]
if 'PREBUILD' in GlobalData.gCommandLineDefines.keys():
self.Prebuild = GlobalData.gCommandLineDefines.get('PREBUILD')
else:
self.Db.InitDatabase()
self.Db_Flag = True
Platform = self.Db._MapPlatform(str(self.PlatformFile))
self.Prebuild = str(Platform.Prebuild)
if self.Prebuild:
PrebuildList = self.Prebuild.split()
if not os.path.isabs(PrebuildList[0]):
PrebuildList[0] = mws.join(self.WorkspaceDir, PrebuildList[0])
if os.path.isfile(PrebuildList[0]):
self.PrebuildScript = PrebuildList[0]
self.Prebuild = ' '.join(PrebuildList)
self.Prebuild += self.PassCommandOption(self.BuildTargetList, self.ArchList, self.ToolChainList)
#self.LaunchPrebuild()
else:
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]))
def InitPostBuild(self):
if 'POSTBUILD' in GlobalData.gCommandLineDefines.keys():
self.Postbuild = GlobalData.gCommandLineDefines.get('POSTBUILD')
else:
Platform = self.Db._MapPlatform(str(self.PlatformFile))
self.Postbuild = str(Platform.Postbuild)
if self.Postbuild:
PostbuildList = self.Postbuild.split()
if not os.path.isabs(PostbuildList[0]):
PostbuildList[0] = mws.join(self.WorkspaceDir, PostbuildList[0])
if os.path.isfile(PostbuildList[0]):
self.PostbuildScript = PostbuildList[0]
self.Postbuild = ' '.join(PostbuildList)
self.Postbuild += self.PassCommandOption(self.BuildTargetList, self.ArchList, self.ToolChainList)
#self.LanuchPostbuild()
else:
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]))
def PassCommandOption(self, BuildTarget, TargetArch, ToolChain):
BuildStr = ''
if GlobalData.gCommand and isinstance(GlobalData.gCommand, list):
BuildStr += ' ' + ' '.join(GlobalData.gCommand)
TargetFlag = False
ArchFlag = False
ToolChainFlag = False
if GlobalData.gOptions and not GlobalData.gOptions.BuildTarget:
TargetFlag = True
if GlobalData.gOptions and not GlobalData.gOptions.TargetArch:
ArchFlag = True
if GlobalData.gOptions and not GlobalData.gOptions.ToolChain:
ToolChainFlag = True
if TargetFlag and BuildTarget:
if isinstance(BuildTarget, list) or isinstance(BuildTarget, tuple):
BuildStr += ' -b ' + ' -b '.join(BuildTarget)
elif isinstance(BuildTarget, str):
BuildStr += ' -b ' + BuildTarget
if ArchFlag and TargetArch:
if isinstance(TargetArch, list) or isinstance(TargetArch, tuple):
BuildStr += ' -a ' + ' -a '.join(TargetArch)
elif isinstance(TargetArch, str):
BuildStr += ' -a ' + TargetArch
if ToolChainFlag and ToolChain:
if isinstance(ToolChain, list) or isinstance(ToolChain, tuple):
BuildStr += ' -t ' + ' -t '.join(ToolChain)
elif isinstance(ToolChain, str):
BuildStr += ' -t ' + ToolChain
return BuildStr
def LaunchPrebuild(self):
if self.Prebuild:
EdkLogger.info("\n- Prebuild Start -\n")
self.LaunchPrebuildFlag = True
PrebuildEnvFile = os.path.join(GlobalData.gConfDirectory,'.cache','.PrebuildEnv')
if os.path.isfile(PrebuildEnvFile):
os.remove(PrebuildEnvFile)
if os.path.isfile(self.PlatformBuildPath):
os.remove(self.PlatformBuildPath)
if sys.platform == "win32":
args = ' && '.join((self.Prebuild, 'set > ' + PrebuildEnvFile))
Process = Popen(args, stdout=PIPE, stderr=PIPE)
else:
args = ' && '.join((self.Prebuild, 'env > ' + PrebuildEnvFile))
Process = Popen(args, stdout=PIPE, stderr=PIPE, shell=True, executable="/bin/bash")
# launch two threads to read the STDOUT and STDERR
EndOfProcedure = Event()
EndOfProcedure.clear()
if Process.stdout:
StdOutThread = Thread(target=ReadMessage, args=(Process.stdout, EdkLogger.info, EndOfProcedure))
StdOutThread.setName("STDOUT-Redirector")
StdOutThread.setDaemon(False)
StdOutThread.start()
if Process.stderr:
StdErrThread = Thread(target=ReadMessage, args=(Process.stderr, EdkLogger.quiet, EndOfProcedure))
StdErrThread.setName("STDERR-Redirector")
StdErrThread.setDaemon(False)
StdErrThread.start()
# waiting for program exit
Process.wait()
if Process.stdout:
StdOutThread.join()
if Process.stderr:
StdErrThread.join()
if Process.returncode != 0 :
EdkLogger.error("Prebuild", PREBUILD_ERROR, 'Prebuild process is not success!')
if os.path.exists(PrebuildEnvFile):
f = open(PrebuildEnvFile)
envs = f.readlines()
f.close()
envs = itertools.imap(lambda l: l.split('=',1), envs)
envs = itertools.ifilter(lambda l: len(l) == 2, envs)
envs = itertools.imap(lambda l: [i.strip() for i in l], envs)
os.environ.update(dict(envs))
EdkLogger.info("\n- Prebuild Done -\n")
def LanuchPostbuild(self):
if self.Postbuild:
EdkLogger.info("\n- Postbuild Start -\n")
if sys.platform == "win32":
Process = Popen(self.Postbuild, stdout=PIPE, stderr=PIPE)
else:
Process = Popen(self.Postbuild, stdout=PIPE, stderr=PIPE, shell=True, executable="/bin/bash")
# launch two threads to read the STDOUT and STDERR
EndOfProcedure = Event()
EndOfProcedure.clear()
if Process.stdout:
StdOutThread = Thread(target=ReadMessage, args=(Process.stdout, EdkLogger.info, EndOfProcedure))
StdOutThread.setName("STDOUT-Redirector")
StdOutThread.setDaemon(False)
StdOutThread.start()
if Process.stderr:
StdErrThread = Thread(target=ReadMessage, args=(Process.stderr, EdkLogger.quiet, EndOfProcedure))
StdErrThread.setName("STDERR-Redirector")
StdErrThread.setDaemon(False)
StdErrThread.start()
# waiting for program exit
Process.wait()
if Process.stdout:
StdOutThread.join()
if Process.stderr:
StdErrThread.join()
if Process.returncode != 0 :
EdkLogger.error("Postbuild", POSTBUILD_ERROR, 'Postbuild process is not success!')
EdkLogger.info("\n- Postbuild Done -\n")
## Build a module or platform ## Build a module or platform
# #
# Create autogen code and makefile for a module or platform, and the launch # Create autogen code and makefile for a module or platform, and the launch
@ -1414,6 +1587,7 @@ class Build():
## Build active platform for different build targets and different tool chains ## Build active platform for different build targets and different tool chains
# #
def _BuildPlatform(self): def _BuildPlatform(self):
SaveFileOnChange(self.PlatformBuildPath, '# DO NOT EDIT \n# FILE auto-generated\n', False)
for BuildTarget in self.BuildTargetList: for BuildTarget in self.BuildTargetList:
GlobalData.gGlobalDefines['TARGET'] = BuildTarget GlobalData.gGlobalDefines['TARGET'] = BuildTarget
for ToolChain in self.ToolChainList: for ToolChain in self.ToolChainList:
@ -1587,6 +1761,7 @@ class Build():
## Build a platform in multi-thread mode ## Build a platform in multi-thread mode
# #
def _MultiThreadBuildPlatform(self): def _MultiThreadBuildPlatform(self):
SaveFileOnChange(self.PlatformBuildPath, '# DO NOT EDIT \n# FILE auto-generated\n', False)
for BuildTarget in self.BuildTargetList: for BuildTarget in self.BuildTargetList:
GlobalData.gGlobalDefines['TARGET'] = BuildTarget GlobalData.gGlobalDefines['TARGET'] = BuildTarget
for ToolChain in self.ToolChainList: for ToolChain in self.ToolChainList:
@ -1961,7 +2136,7 @@ def Main():
# Initialize log system # Initialize log system
EdkLogger.Initialize() EdkLogger.Initialize()
GlobalData.gCommand = sys.argv[1:]
# #
# Parse the options and args # Parse the options and args
# #
@ -2059,7 +2234,8 @@ def Main():
MyBuild = Build(Target, Workspace, Option) MyBuild = Build(Target, Workspace, Option)
GlobalData.gCommandLineDefines['ARCH'] = ' '.join(MyBuild.ArchList) GlobalData.gCommandLineDefines['ARCH'] = ' '.join(MyBuild.ArchList)
MyBuild.Launch() if not (MyBuild.LaunchPrebuildFlag and os.path.exists(MyBuild.PlatformBuildPath)):
MyBuild.Launch()
# Drop temp tables to avoid database locked. # Drop temp tables to avoid database locked.
for TmpTableName in TmpTableDict: for TmpTableName in TmpTableDict:
SqlCommand = """drop table IF EXISTS %s""" % TmpTableName SqlCommand = """drop table IF EXISTS %s""" % TmpTableName
@ -2116,7 +2292,11 @@ def Main():
Utils.ClearDuplicatedInf() Utils.ClearDuplicatedInf()
if ReturnCode == 0: if ReturnCode == 0:
Conclusion = "Done" try:
MyBuild.LanuchPostbuild()
Conclusion = "Done"
except:
Conclusion = "Failed"
elif ReturnCode == ABORT_ERROR: elif ReturnCode == ABORT_ERROR:
Conclusion = "Aborted" Conclusion = "Aborted"
else: else: