英文:
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 <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.
答案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
工具链文件。另一种方式是在 CMakeLists
的 project()
调用之前设置变量 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".
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论