27

I am trying to simplify a large project by having cmake compile it all for me, but i am having trouble compiling the boost unit tests. The cmake file for my simple example is shown below.

cmake_minimum_required(VERSION 2.8)
find_package(Boost COMPONENTS system filesystem REQUIRED)
add_excecutable(testTheTester boostTester.cpp)
target_link_libraries(testTheTester ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY})
add_test(tester tester)

and the code in boostTester.cpp is:

#define BOOST_TEST_MAIN
#if !defined( WIN32 )
    #define BOOST_TEST_DYN_LINK
#endif
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE( la ) {
    BOOST_CHECK_EQUAL(1, 1)
}

Now this cpp code will compile and run fine if i build it manually with:

g++ boostTester.cpp -o output -lboost_unit_test_framework

and the cmake works fine but when using the output make file the make crashes with a huge amount of errors the first of which is this:

undefined referance to 'boost::unit_test::unit_test_log_t::set_checkpoint(boost... bla bla

now my initial thought is that the cmake is not linking the boost library correctly and I have tried many commands and combinations with no luck. Does anyone know how to link the boost_unit_test in a cmake file?

Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175

2 Answers2

24

You need to include the unit test framework in the list of requirements in the find_package command, and then link it:

find_package(Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
...
target_link_libraries(testTheTester
                      ${Boost_FILESYSTEM_LIBRARY}
                      ${Boost_SYSTEM_LIBRARY}
                      ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
                      )
Fraser
  • 74,704
  • 20
  • 238
  • 215
  • Cheers, this worked a charm, as a note, how do you find these packages and what they are named for future use? – Fantastic Mr Fox Mar 27 '12 at 00:35
  • I think they generally match the output of `bjam --show-libraries`. Test is one of the exceptions (maybe the only one?) to the convention that the lib name reflects the bjam target. The bjam target is simply "test", whereas the library name includes "unit_test_framework". CMake's module seems to favour naming its variables in line with the library name rather than the bjam target name. – Fraser Mar 27 '12 at 01:13
  • @Fraser @Ben Simply add `unit_test_framework` to your `FIND_PACKAGE`command and then simply use `${Boost_LIBRARIES}` in the `target_link_libraries` command. For the names: They are just the library file names without the `boost_`|`libboost_` prefix. – Johannes S. Apr 02 '12 at 08:49
  • 1
    @JohannesS. Yes - that's a good option if you do want all the boost libs found in the `find_package` command linked in. However, it's common to not need them all for all targets. For example, the unit test framework library probably doesn't need to be linked to the main production library or executable. – Fraser Apr 02 '12 at 09:44
  • 1
    @Fraser No, according to code and documentation in `FindBoost.cmake`, `${Boost_LIBRARIES}` only contains those libraries that you listed in the `FIND_PACKAGE(...)` command. No over-linking. – Johannes S. Apr 02 '12 at 20:31
  • @JohannesS. Indeed - but my point is that you may not want to link *all* the boost libs found using `find_package` to every target defined in that CMakeLists.txt – Fraser Apr 02 '12 at 20:34
  • @Fraser Alright, now I get it. Thank you for your patience ;) (*Technically*, it would be possible to issue a new `FIND_PACKAGE`command, but I guess that wouldn't help anybody (I never did this)). – Johannes S. Apr 02 '12 at 22:15
2

Nowadays in CMake 3, I'd recommend using the exported namespace targets instead of variables. If you have a typo, Fraser's answer fails to link. Also, specify the linkage type explicitly if you can.

find_package(Boost CONFIG COMPONENTS system filesystem unit_test_framework REQUIRED)
...
target_link_libraries(testTheTester
  PRIVATE
  Boost::filesystem
  Boost::system
  Boost::unit_test_framework
  )
Ryan Friedman
  • 115
  • 1
  • 9