Search code examples
subprocesscallscons

SCons strange execution order


My goal is to executeboost::testunit tests in SCons. In the SConstruct file I have following piece of code:

for t in toTest:
    nextTest = SConscript('#/test/' + t + '/SConscript',  
                          variant_dir = test_dir + t,
                          duplicate = 0) 
    for a in nextTest:
        import subprocess
        subprocess.call(a.abspath)

Sconscript assigned to nextTest returns a Program:

prgs = env.Program( 'model_test_exe', 
                    'ModelTest.cpp', 
                     LIBPATH = [boost_lib, python_lib], 
                     LIBS = [modellib])

Return('prgs')

This problem is following error occuring after scons -c command. Next time i run scons it gives me:

C:\Users\...>scons -Q
WindowsError: [Error 2] The system cannot find the file specified:
  File "C:\Users\...\Win32Project4\SConstruct", line 51:
    subprocess.call(a.abspath)

It looks like before the Program is created by Sconscript the call is executed. What can I do with this? I'm new to SCons and I'm done with hide and seek with this tool. It literally executes before anything else (no .obj/.lib files are created).

Moreover the code works, because I can compile it to .exe when I change subprocess to Alias. However this is not what I want. My goal is to print tests results during the build.


Solution

  • O.k. your problem is that you are using subprocess to launch processes instead of creating a builder or using Command().

    SCons runs in several phases, the first of which is to process all the SConstruct/SConscript logic which starts building a dependency graph.

    After SCons runs scanners, and builds the full dependency tree, it then walks that tree and runs commands.

    Thus your subprocesses get run before SCons can even start building anything.

    Here's an unpolished explanation: https://bitbucket.org/scons/scons/wiki/SconsProcessOverview

    You might try dropping the for nextTest loop from your SConstruct, instead putting something like this in your SConscripts

    prgs = env.Program( 'model_test_exe', 
                        'ModelTest.cpp', 
                         LIBPATH = [boost_lib, python_lib], 
                         LIBS = [modellib])
    
    env.Command('outputfile_for_test',prgs,'$SOURCE > $TARGET')
    
    
    
    Return('prgs')
    

    Note that a lot of this is covered in the Users Guide. http://scons.org/doc/production/HTML/scons-user/index.html