Search code examples
c++scons

Scons and Boost.Test, my Test project cannot link with my main project object files


I'd like to use Boost.Test for Test Driven Development.

I asked scons to create two executables, the main one, and the test one. All my main project files are in ./src/, and all my test dedicated files are in ./test/

The problem is:

  • the main project object files are put in ./build/src/
  • the test project object files are put in ./build/test/

and in such a configuration my executable Test cannot link since all the main project object files (of the classes on which I perform my tests) are not in the same directory.

Do you have an idea how I could tweak my scons file so as the linking of the executable Test can use the object files in ./src./ ?

Below is my main.scons file:

import os
env=Environment(CPPPATH=['/usr/local/boost/boost_1_52_0/boost/','./src/'],
                CPPDEFINES=[],
                LIBPATH=['/usr/local/boost/boost_1_52_0/boost/libs/','.'],
                LIBS=['boost_regex'],
                CXXFLAGS="-std=c++0x")
env['ENV']['TERM'] = os.environ['TERM']
env.Program('Main', Glob('src/*.cpp'))

#
testEnv = env.Clone()
testEnv['CPPPATH'].append('./test/')
testEnv['LIBS'].append('boost_unit_test_framework')
testEnv.Program('Test', Glob('test/*.cpp'))

Solution

  • While the "duplicate object lists" approach is fine for simple projects, you may run into limitations in which your test code doesn't need to link against the entire object space of your main program. For example, to stub out a database layer that's not the focus of a particular unit test.

    As an alternative, you can create (static) libraries of common code that you link against your primary executable and your test framework.

    common_sources = ['src/foo.cpp', 'src/bar.cpp'] # or use Glob and then filter
    env.Library("common", common_sources)
    program_sources = ['src/main.cpp']
    env.Program("my_program", program_sources, LIBS=['common'])
    ...
    testEnv['LIBPATH'] = ['.']  # or wherever you build the library
    testEnv.Program("unit_test", test_sources, LIBS=['common'])
    

    This also avoids the duplicate main() problem that you mention because only the program_sources and test_sources lists should contain the appropriate file with the main routine.