Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scons - how to run something /after/ all targets have been built

I've recently picked up scons to implement a multi-platform build framework for a medium sized C++ project. The build generates a bunch of unit-tests which should be invoked at the end of it all. How does one achieve that sort of thing?

For example in my top level sconstruct, I have

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)

Each of the subdir has its unit-tests, however, since there are dependencies between the dlls and executables built inside them - i want to hold the running of tests until all the subdirs have been built and installed (I mean, using env.Install).

Where should I write the loop to iterate through the built tests and execute them? I tried putting it just after this loop - but since scons doesn't let you control the order of execution - it gets executed well before I want it to.

Please help a scons newbie. :)

thanks,

like image 481
ajd. Avatar asked Dec 10 '09 16:12

ajd.


People also ask

How can I speed up my SCons?

The command 'scons --max-drift=1 --implicit-deps-unchanged' will execute your build as fast as possible.

What is SCons command?

DESCRIPTION. The scons utility builds software (or other files) by determining which component pieces must be rebuilt and executing the necessary commands to rebuild them.

What is SConstruct?

The SConstruct File. If you're used to build systems like Make you've already figured out that the SConstruct file is the SCons equivalent of a Makefile. That is, the SConstruct file is the input file that SCons reads to control the build.


1 Answers

SCons, like Make, uses a declarative method to solving the build problem. You don't want to tell SCons how to do its job. You want to document all the dependencies and then let SCons solve how it builds everything.

If something is being executed before something else, you need to create and hook up the dependencies.

If you want to create dmy touch files, you can create a custom builder like:

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)

It is very important to put the timestamp into the dummy file, because scons uses md5 hashes. If you have an empty file, the md5 will always be the same and it may decide to not do subsequent build steps. If you need to generate different tweaks on a basic command, you can use function factories to modify a template. 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)

If you have something that you want to automatically inject into the scons build flow ( e.g. something that compresses all your build log files after everything else has run ), see my question here.

like image 146
Ross Rogers Avatar answered Sep 29 '22 06:09

Ross Rogers