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

时间:2009-12-10 16:27:48

标签: unit-testing build-automation 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)

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

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

请帮助一个scons新手。 :)

感谢,

4 个答案:

答案 0 :(得分:5)

SCons和Make一样,使用声明性方法来解决构建问题。你不想告诉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)

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

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)

如果您想要自动注入scons构建流程(例如,在其他所有内容运行后压缩所有构建日志文件的内容),请参阅my question here

答案 1 :(得分:2)

解决方案应该像这样简单。

使测试构建器的结果取决于“安装”构建器的结果

在伪:

test = Test(dlls)
result = Install(dlls)
Depends(test,result)

最好的方法是,如果“测试”构建器实际上为您计算了dll依赖项,但可能有各种原因它不会这样做。

答案 2 :(得分:0)

就依赖性而言,您希望所有测试操作依赖于所有程序构建的操作。这样做的一种方法是创建虚拟目标并将其导出到所有子目录的sconscript文件,并在sconscript文件中,在主目标上创建虚拟目标Depends,并拥有测试目标{{ 1}}在虚拟目标上。

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

(在顶级SConstruct中)

Depends

(在每个子目录的SConscript中)

dummy = env.Command('.all_built', 'SConstruct', 'echo Targets built. > $TARGET')
Export('dummy')

我确信可以进行进一步的改进,但也许这会让你开始。

编辑:也值得指出this page这个主题。

答案 3 :(得分:0)

让每个SConscript返回一个您将构建依赖关系的值。

SConscript文件:

test = debug_environment.Program('myTest', src_files)
Return('test')

SConstruct文件:

dep1 = SConscript([...])
dep2 = SConscript([...])
Depends(dep1, dep2)

现在dep1构建将在dep2构建完成后完成。