scons - 如何运行/后/所有目标已经建立

ajd*_*jd. 5 build-automation unit-testing scons

我最近选择了scons来为中型C++项目实现一个多平台构建框架.构建生成了一堆单元测试,应该在它的最后调用.如何实现这种目标?

例如,在我的顶级sconstruct中,我有

subdirs=['list', 'of', 'my', 'subprojects']
for subdir in subdirs:
    SConscript(dirs=subdir, exports='env', name='sconscript',
       variant_dir=subdir+os.sep+'build'+os.sep+mode, duplicate=0)
Run Code Online (Sandbox Code Playgroud)

每个subdir都有它的单元测试,但是,因为dll和它们内置的可执行文件之间存在依赖关系 - 我想保持测试的运行,直到所有的子目录都已构建和安装(我的意思是,使用env.Install ).

我应该在哪里编写循环来迭代构建的测试并执行它们?我试着把它放在这个循环之后 - 但是因为scons不能让你控制执行的顺序 - 它会在我想要之前执行得很好.

请帮助一个scons新手.:)

谢谢,

Ros*_*ers 5

像Make一样,SCons使用声明性方法来解决构建问题.你不想告诉SCons如何完成它的工作.您希望记录所有依赖项,然后让SCons解决它如何构建所有内容.

如果在其他东西之前执行某些操作,则需要创建并连接依赖项.

如果要创建dmy touch文件,可以创建自定义构建器,如:

import time

def action(target, source, env):
    os.system('echo here I am running other build')
    dmy_fh = open('dmy_file','w')
    dmy_fh.write( 'Dummy dependency file created at %4d.%02d.%02d %02dh%02dm%02ds\n'%time.localtime()[0:6])
    dmy_fh.close()

bldr = Builder(action=action)
env.Append( BUILDERS = {'SubBuild' : bldr } )

env.SubBuild(srcs,tgts)
Run Code Online (Sandbox Code Playgroud)

将时间戳放入虚拟文件非常重要,因为scons使用md5哈希值.如果您有一个空文件,则md5将始终相同,并且可能决定不执行后续构建步骤.如果需要在基本命令上生成不同的调整,可以使用函数工厂来修改模板.例如

def gen_a_echo_cmd_func(echo_str):
    def cmd_func(target,source,env):
        cmd = 'echo %s'%echo_str
        print cmd
        os.system(cmd)
    return cmd_fun

bldr = Builder(action = gen_a_echo_cmd_func('hi'))
env.Append(BUILDERS = {'Hi': bldr})
env.Hi(srcs,tgts)

bldr = Builder(action = gen_a_echo_cmd_func('bye'))
env.Append(BUILDERS = {'Bye': bldr})
env.Bye(srcs,tgts)
Run Code Online (Sandbox Code Playgroud)

如果你有想要自动注入scons构建流程的东西(比如在其他所有东西运行后压缩所有构建日志文件的东西),请在此处查看我的问题.


Aid*_*lly 0

就依赖性而言,您希望所有测试操作都依赖于所有程序构建的操作。Depends执行此操作的一种方法是创建一个虚拟目标并将其导出到所有子目录的 sconscript 文件,并在 sconscript 文件中,在主目标上创建虚拟目标,并将测试目标Depends放在虚拟目标上。

我在弄清楚如何设置虚拟目标时遇到了一些麻烦,但这基本上是有效的:

(在顶级 SConstruct 中)

dummy = env.Command('.all_built', 'SConstruct', 'echo Targets built. > $TARGET')
Export('dummy')
Run Code Online (Sandbox Code Playgroud)

(在每个子目录的SConscript中)

Import('dummy')
for target in target_list:
  Depends(dummy, targe)
for test in test_list:
  Depends(test, dummy)
Run Code Online (Sandbox Code Playgroud)

我确信可以进行进一步的改进,但这也许可以帮助您开始。

编辑:还值得指出有关该主题的页面