在Buildbot中,我需要能够在编译步骤之前“获取”环境。
如果我使用bash从命令行构建应用程序,我将不得不这样做:
. envrionment-set-up-script
build_command
在build bot master.cfg文件中,我尝试了以下内容:
factory.addStep(ShellCommand(command=["source","environment-set-up-script"])
factory.addStep(ShellCommand(command=[".","environment-set-up-script"]))
factory.addStep(Configure(command=["source","environment-set-up-script"]))
factory.addStep(Configure(command=[".","environment-set-up-script"]))
所有这些都失败了,这是因为无法找到命令,这是有道理的,因为它是一个内置的bash。
此外,我不认为这是正确的方法,因为在调用工厂的下一步时不一定会使用环境。
在使用OpenEmbedded / Yocto时,我们以类似于此的方式解决了问题:
class EnvStep(ShellCommand):
def __init__(self, command='', **kwargs):
kwargs['command'] = [
'bash', '-c', 'source environment-set-up-script; %s' % command
]
ShellCommand.__init__(self, **kwargs)
然后,添加一个将EnvStep
参数设置为command
的foo
让我们在foo
源环境中运行environment-set-up-script
。换句话说,您可以通过调用来使用该步骤
factory.addStep(EnvStep(command='foo'))
采购将自动进行。
我们还有一些其他自定义构建步骤需要build-env来源,因此我们只需让它们为EnvStep
而不是ShellCommand
进行子类化,以便自动处理环境。
经过一些实验,我找到了实现这一目标的方法。你需要:
注意:应该将环境解析为可以用作env参数的字典
from buildbot.process.factory import BuildFactory
from buildbot.steps.shell import ShellCommand, SetProperty
from buildbot.process.properties import Property
def glob2list(rc, stdout, stderr):
''' Function used as the extrat_fn function for SetProperty class
This takes the output from env command and creates a dictionary of
the environment, the result of which is stored in a property names
env'''
if not rc:
env_list = [ l.strip() for l in stdout.split('\n') ]
env_dict={ l.split('=',1)[0]:l.split('=',1)[1] for l in
env_list if len(l.split('=',1))==2}
return {'env':env_dict}
#This is the equivalent of running source MyWorkdir/my-shell-script then
#capturing the environment afterwords.
factory.addStep(SetProperty(command="bash -c env",
extract_fn=glob2list,
workdir='MyWorkdir',
env={BASH_ENV':'my-shell-script' }))
#Do another step with the environment that was sourced from
#MyWorkdir/my-shell-script
factory.addStep(ShellCommand(command=["env"],
workdir="MyWorkdir",
env=Property('env')))
您可以将env
参数用于ShellCommand构建步骤,以便为命令设置环境。 (http://docs.buildbot.net/0.8.1/Using-ShellCommands.html)
如果希望环境同等地应用于所有构建命令,也可以在启动构建从属之前设置环境。
基本上:
Visual Studio开发的一个示例也很有用。
通过使用通用工具脚本,为每台机器设置了正确的env,同一构建器可以使用VS的多个版本,并支持多种本机和交叉架构。
# A raw text string to get around windows quoting problems in buildbot.
vscomntools=r""""%VS120COMNTOOLS%\VsDevCmd.bat" %PROCESSOR_ARCHITECTURE% & set"""
# Determine MSVC Environment using VS Common Tools for build steps.
f.addStep(SetProperty(
command=vscomntools,
extract_fn=glob2list))
另一种方法是通过尝试引用批处理文件&和命令来启动每个命令。
steps.ShellCommand(
name = "Example",
command = ["/bin/bash", "-c", "source <BASH SCRIPT>"],
haltOnFailure = True,
description = "Example"
),
我有点不同地解决了这个问题。我在Windows worker上安装批处理文件,在启动时调用环境设置批处理文件,然后执行预期的命令。当然,批处理文件在转发参数方面非常糟糕,以及Visual Studio 2017的VsDevCmd.bat破坏了你的cwd这一事实,这更加困难。但是,如果在worker上安装以下文件,则可以使用VS2017进行构建:
@ECHO OFF
@REM Calls a single command from the environment set from visual studio vcvars.
@REM Usage:
@REM withvcvars-2017.bat <arch> [command]
@REM
@REM Run VsDevCmd.bat /help to see available arches
@REM See below instantiation for more fine grained option setting.
set ARCH=%1
shift
setlocal enabledelayedexpansion
@rem Replace __ with = in batch files.
@rem This works around idiotic lack of equals signs in args
@rem args contains full args string with substitutions in place
:argloop
if "%~1" NEQ "" (
set str=%~1
set out=!str:__==!
set %~1=!out!
set args=!args!!out!
SHIFT
goto :argloop
)
@rem Aside from batch files being too moronic to allow for equals signs in args,
@rem VsDevCmd.bat idiotically clobbers the current working directory when it's called.
set CWD=%cd%
echo Calling VsDevCmd.bat for arch %ARCH%
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" -arch=%ARCH% -winsdk=8.1 -app_platform=Desktop -no_logo
@rem Who lets these things out the door?
cd %CWD%
@ECHO ON
%args%
完成此操作后,您可以在bulidbot主逻辑中创建一个附加此批处理文件的函数:
def _withvcvars(year, arch, cmd):
base_cmd = ["%swithvcvars-%s.bat" % ('\\path\\to\\batchfile\\', year), arch]
return base+cmd
这使您可以运行命令,其中您调用msbuild.exe,该命令在其参数中需要等号。只需将它们指定为双下划线:
withvcvars-2017.bat amd64 msbuild.exe your.sln /p:Configuration__Release /p:Platform__x64