Problem linking to Catch2 library installed with Conan 2.0 in CMake

762 Views Asked by At

I recreated my issue on smaller project. Let's assume there are these files (also build directory):

├── add.hpp
├── add-test.cpp
├── CMakeLists.txt
└── conanfile.txt

add.hpp:

inline int add(int a, int b) { return a + b; }

add-test.cpp:

#include <catch2/catch_all.hpp>
#include "add.hpp"

TEST_CASE("testing add") {
    REQUIRE(add(1, 1) == 2);
}

conanfile.txt:

[requires]
catch2/3.3.1

[generators]
CMakeDeps
CMakeToolchain

I use the following CMake script to build all of this:

cmake_minimum_required(VERSION 3.5)

project(add LANGUAGES CXX VERSION 0.0.0)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_TOOLCHAIN_FILE "build/conan_toolchain.cmake")
# Required to be set.
set(CMAKE_BUILD_TYPE "Debug")
# CMake can't find Conan packages without these two lines
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})

find_package(Catch2 REQUIRED)

include_directories(${Catch2_INCLUDE_DIR})

add_executable(add-test add-test.cpp)

target_link_libraries(add-test Catch2::Catch2WithMain)

Conan profile is:

[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=12.2
os=Linux

I use the following commands to build my project (Assuming build/ is empty):

conan install . --output-folder=build --build=missing
cd build
cmake ..
cmake --build .

CMake configuration and Conan install go fine, then when building I get a swarm of linker errors, all are connected with Catch2. Some of them are like this:

/usr/bin/ld: CMakeFiles/add-test.dir/add-test.cpp.o: in function `Catch::BinaryExpr<int, int>::~BinaryExpr()':
/home/fungor/.conan2/p/catchff10ed8b5da5a/p/include/catch2/internal/catch_decomposer.hpp:73: undefined reference to `Catch::ITransientExpression::~ITransientExpression()'
/usr/bin/ld: CMakeFiles/add-test.dir/add-test.cpp.o:(.data.rel.ro._ZTIN5Catch10BinaryExprIiiEE[_ZTIN5Catch10BinaryExprIiiEE]+0x10): undefined reference to `typeinfo for Catch::ITransientExpression'
/usr/bin/ld: CMakeFiles/add-test.dir/add-test.cpp.o: in function `Catch::BinaryExpr<int, int>::streamReconstructedExpression(std::ostream&) const':
/home/fungor/.conan2/p/catchff10ed8b5da5a/p/include/catch2/internal/catch_decomposer.hpp:80: undefined reference to `Catch::formatReconstructedExpression(std::ostream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Catch::StringRef, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
... (a bunch more of these undefined references)

What am I doing wrong?

I tried:

  • clearing Conan cache, rebuilding packages
  • different Conan profiles: different CPP standards, build configs.

I just need Catch2 to work with my project.

this seems similar to mine, but in my case libstdc++ is already set to ...++11

EDIT 1: Stripped question to be more minimal.

EDIT 2: Recreated my problem on smaller scale.

EDIT 3: Included information about conanfile.txt and corrected CMake script.

2

There are 2 best solutions below

4
SpacePotatoes On BEST ANSWER

To begin with, change your CMakeLists:

cmake_minimum_required(VERSION 3.8)
project(add LANGUAGES CXX VERSION 0.0.0)

find_package(Catch2 REQUIRED)

add_executable(add-test add-test.cpp)
target_link_libraries(add-test PRIVATE Catch2::Catch2WithMain)
target_compile_features(add-test PRIVATE cxx_std_17)

And the way you call conan & cmake:

conan install . -of build-debug -s build_type=Debug -b missing 
cmake -S . -B build-debug -DCMAKE_TOOLCHAIN_FILE=build-debug/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug
cmake --build build-debug

Always try to set CMake toolchain file in command line arguments. Another way is to set variable CMAKE_TOOLCHAIN_FILE before project() call in CMakeLists. The last one is not a good practice anyway.

2
JackCarterSmith On

This may be due to a configuration conflict.

The libs are compiled in Release configuration, but my working project is build using Debug configuration. Some links are missing in CMake target of linked libs...

So beware of conflict between both.

EDIT: @Yunnosh, I'm taking note, and no I wasn't aware of this post, it's not like I had hours ahead of me to read every stack (no sarcasm). So, I updated the post to be more like an "answer".