Problem linking to Catch2 library installed with Conan 2.0 in CMake.

huangapple go评论70阅读模式
英文:

Problem linking to Catch2 library installed with Conan 2.0 in CMake

问题

我重新在一个较小的项目上重现了我的问题。让我们假设有这些文件(还有构建目录):

├── 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

我使用以下的CMake脚本来构建所有这些:

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配置文件是:

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

我使用以下命令来构建我的项目(假设build/是空的):

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

CMake配置和Conan安装都进行得很顺利,然后在构建时,我遇到了一堆与Catch2相关的链接错误,其中一些如下所示:

/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&)'
...(还有一堆这些未定义引用)

我做了什么错了?

我尝试过:

  • 清除Conan缓存,重新构建包
  • 不同的Conan配置文件:不同的CPP标准,构建配置。

我只需要让Catch2与我的项目一起工作。

英文:

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 &lt;catch2/catch_all.hpp&gt;
#include &quot;add.hpp&quot;

TEST_CASE(&quot;testing add&quot;) {
    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 &quot;build/conan_toolchain.cmake&quot;)
# Required to be set.
set(CMAKE_BUILD_TYPE &quot;Debug&quot;)
# CMake can&#39;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&lt;int, int&gt;::~BinaryExpr()&#39;:
/home/fungor/.conan2/p/catchff10ed8b5da5a/p/include/catch2/internal/catch_decomposer.hpp:73: undefined reference to `Catch::ITransientExpression::~ITransientExpression()&#39;
/usr/bin/ld: CMakeFiles/add-test.dir/add-test.cpp.o:(.data.rel.ro._ZTIN5Catch10BinaryExprIiiEE[_ZTIN5Catch10BinaryExprIiiEE]+0x10): undefined reference to `typeinfo for Catch::ITransientExpression&#39;
/usr/bin/ld: CMakeFiles/add-test.dir/add-test.cpp.o: in function `Catch::BinaryExpr&lt;int, int&gt;::streamReconstructedExpression(std::ostream&amp;) const&#39;:
/home/fungor/.conan2/p/catchff10ed8b5da5a/p/include/catch2/internal/catch_decomposer.hpp:80: undefined reference to `Catch::formatReconstructedExpression(std::ostream&amp;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, Catch::StringRef, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;)&#39;
... (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.

答案1

得分: 2

要开始,更改你的 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)

而你调用 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

总是尝试在命令行参数中设置 CMake 工具链文件。另一种方式是在 CMakeListsproject() 调用之前设置变量 CMAKE_TOOLCHAIN_FILE。不过最后一种方式并不是一个好做法。

英文:

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

得分: 0

这可能是由于配置冲突引起的。

这些库是在Release配置下编译的,但我的工作项目是使用Debug配置构建的。
一些链接在链接库的CMake目标中丢失了...

所以要小心两者之间的冲突。

编辑:@Yunnosh,我已经注意到了,不,我不知道这篇帖子,不是因为我有很多时间来阅读每个堆栈(没有讽刺意味)。
所以,我更新了帖子,使其更像一个“答案”。

英文:

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".

huangapple
  • 本文由 发表于 2023年5月7日 02:45:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76190559.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定