使用Conan 2.0安装的Catch2库在CMake中链接失败求助
Catch2链接错误排查与解决
问题复现
项目文件结构:
- add.hpp
- add-test.cpp
- CMakeLists.txt
- conanfile.txt
- build/
各文件内容:
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
原CMakeLists.txt
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
构建命令
conan install . --output-folder=build --build=missing cd build cmake .. cmake --build .
错误信息
构建时出现大量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()' ...
问题原因
- 构建类型不匹配:Conan安装依赖时使用
Release构建类型(配置文件中build_type=Release),但CMake手动设置CMAKE_BUILD_TYPE=Debug,导致编译生成的目标文件(Debug)与链接的Catch2库(Release)构建类型不一致,符号无法匹配。 - CMake配置错误:
CMAKE_TOOLCHAIN_FILE设置位置错误,必须在project命令之前,否则toolchain配置无法生效。- 手动设置
CMAKE_BUILD_TYPE会覆盖ConanToolchain传递的构建类型,导致不一致。 include_directories(${Catch2_INCLUDE_DIR})属于冗余配置,find_package(Catch2 REQUIRED)后,Catch2::Catch2WithMain目标已包含头文件路径。
修复方案
1. 统一构建类型
确保Conan安装和CMake编译使用相同的构建类型,二选一即可:
选项A:改用Debug构建类型
修改Conan配置文件的build_type为Debug:
[settings] arch=x86_64 build_type=Debug compiler=gcc compiler.cppstd=gnu17 compiler.libcxx=libstdc++11 compiler.version=12.2 os=Linux
选项B:改用Release构建类型
移除CMakeLists.txt中set(CMAKE_BUILD_TYPE "Debug")这一行,由ConanToolchain传递构建类型。
2. 修正CMakeLists.txt
cmake_minimum_required(VERSION 3.5) # 必须在project之前设置toolchain文件 set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/build/conan_toolchain.cmake") project(add LANGUAGES CXX VERSION 0.0.0) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 移除手动设置的CMAKE_BUILD_TYPE,由ConanToolchain传递 # set(CMAKE_BUILD_TYPE "Debug") list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}) find_package(Catch2 REQUIRED) # 移除冗余的include_directories # include_directories(${Catch2_INCLUDE_DIR}) add_executable(add-test add-test.cpp) target_link_libraries(add-test Catch2::Catch2WithMain)
3. 重新构建
清理旧构建文件后执行命令:
rm -rf build conan install . --output-folder=build --build=missing cd build cmake .. cmake --build .
验证
构建成功后运行测试:
./add-test
内容的提问来源于stack exchange,提问作者Fungor
相关产品推荐
相关产品推荐

