0

I am trying to setup a simple C++ project with CMake and Boost libraries (Boost.Test in this case). I am following this guide except trying to link statically: https://www.jetbrains.com/help/clion/boost-test-support.html. I have installed Boost using this guide: https://www.boost.org/doc/libs/1_73_0/more/getting_started/windows.html and successfully followed step 5 to generate the library binaries.

Using the below CMake configuration, I get this error when trying to build with cmake --build .:

test1.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl boost::unit_test::unit_test_log_t::test_start(unsigned long)" (?test_start@unit_test_log_t@unit_test@boost@@UEAAXK@Z)
tests2.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl boost::unit_test::unit_test_log_t::test_start(unsigned long)" (?test_start@unit_test_log_t@unit_test@boost@@UEAAXK@Z)
MSVCRTD.lib(exe_main.obj) : error LNK2019: unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)

CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
project(cmake_boost_test)

set(CMAKE_CXX_STANDARD 14)

add_executable(cmake_boost_test main.cpp)

add_subdirectory(Boost_tests)

Boost_tests/CMakeLists.txt

set(Boost_DEBUG ON)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost REQUIRED COMPONENTS unit_test_framework)
include_directories(${Boost_INCLUDE_DIRS})

add_executable(Boost_Tests_run test1.cpp tests2.cpp)
target_link_libraries(Boost_Tests_run ${Boost_LIBRARIES})

Boost_tests/test1.cpp

#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

Boost_tests/tests2.cpp

#include <boost/test/unit_test.hpp>
Jordan
  • 902
  • 2
  • 10
  • 37
  • According to the Boost [Library naming](https://www.boost.org/doc/libs/1_42_0/more/getting_started/windows.html#library-naming) scheme, files like `libboost<...>.lib` denotes **static** libraries, and files like `boost<...>.lib` denotes **import** libraries for **dynamic** ones (which in case are named `boost<...>.dll`). It seems you have only static Boost libraries installed. For debug "Could NOT find Boost ..." problems pass `-DBoost_DEBUG=ON` option to `cmake` and check exact filenames which are searched. – Tsyvarev May 08 '20 at 08:53
  • I have exactly same problem, which root is in macro resolution. Linker reports, that it can't found `int main() {}` function. It should be defined by Boost.test, but it does not :( If you found solution, it would be very useful – Borik Bobrujskov Jun 23 '21 at 22:23
  • @BorikBobrujskov My apologies, I don't know exactly how I fixed this issue. I believe it had something to do with the Boost_USE_STATIC_LIBS flag as mentioned in my comment to the answer below. But here is the working project this issue was from (the fix is somewhere in here): https://github.com/JSchneidler/cmake_boost_template – Jordan Jul 13 '21 at 15:49

1 Answers1

0

There are basically 3 steps:

  1. building boost and the relevant libraries and their variant (see here for Boost.Test)
  2. configure the project with CMake (an example here)
  3. build the project

It seems like you have all the steps, but what makes things difficult is that those 3 steps are related and should be done in a coherent manner:

  1. Step 1+2: if you are building specific variants of Boost (or Boost.Test) in step 1, you have to instruct CMake with that variant
  2. Step 3: when you build your project, your code program should in some cases be build with defines that instruct what is the variant being built. For instance if you want to link with the shared library version of Boost.Test, you have to define BOOST_TEST_DYN_LINK (in the code before any include of Boost.Test or with target_compile_definitions(test_executable PRIVATE "BOOST_TEST_DYN_LINK=1"))

In the case of Boost.Test, there is another gotcha: on Windows there is the autolink feature that will instruct the linker to link automatically with one version of a .lib: this is something I usually disable by passing a define BOOST_ALL_NO_LIB.

If you are able to make CMake detect for Boost.Test, I would not bother at the beginning with all those linking issues and use the header variant for which no linking issue is involved.

Coming back to what you have currently:

  • the error Could NOT find Boost (missing: unit_test_framework) (found version 1.60.0") is related to step 1+2: CMake is unable to find the libraries with the configuration you are indicating. Sometimes you need to give more variables to CMake such that it finds the right libraries, but my guess is that you just did not build the shared variant (see here). For instance I use Boost_COMPILER and Boost_ARCHITECTURE sometimes.
  • Boost_USE_STATIC_LIBS is an instruction for CMake only: it will not enforce the compilation of your with the right defines.

If you post the error that you get with CMake by passing -DBoost_DEBUG=ON, we will be able to support you with more precision.

Raffi
  • 3,068
  • 31
  • 33
  • Thank you! I was definitely mistaken about `Boost_USE_STATIC_LIBS`. `Boost_DEBUG` is on, I will update the question with the full error (it is huge). I will eventually switch to header-only as it makes more sense for my small project, though I'd like to understand how to actually link with the libraries (I have the same issue with Boost.Filesystem). – Jordan May 08 '20 at 21:55