Abseil与LibTorch联合编译失败:未定义引用问题求助
Ubuntu 22.04集成Abseil与LibTorch(v2.0)时链接失败
在Ubuntu 22.04环境使用CLion+CMake+Ninja构建项目,同时集成Abseil与LibTorch v2.0,调用absl::StrCat、absl::StrAppend等函数时出现链接错误,报错信息如下:
undefined reference to `absl::StrCat(absl::AlphaNum const&, absl::AlphaNum const&, absl::AlphaNum const&)' undefined reference to `absl::StrAppend(std::string*, absl::AlphaNum const&)'
单独使用Abseil或LibTorch均可正常构建运行,代码在Windows环境也能成功运行,怀疑是CMake配置问题。
项目配置与代码
CMakeLists.txt
cmake_minimum_required(VERSION 3.25) project(simple_tests) set(ABSL_PROPAGATE_CXX_STD ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_CXX_STANDARD 17) set(_GLIBCXX_USE_CXX11_ABI 0) set(CONDA_PREFIX "/home/qzz/.conda/envs/bridge_research/") set(PYTHON_EXECUTABLE "${CONDA_PREFIX}/bin/python") set(PYTHON_INCLUDE_DIR "${CONDA_PREFIX}/include/python3.8") set(PYTHON_LIBRARIES "${CONDA_PREFIX}/lib/libpython3.so") set(CMAKE_CUDA_COMPILER "/usr/local/cuda-11.7/bin/nvcc") set(CMAKE_CUDA_ARCHITECTURES 86) find_package(PythonInterp REQUIRED) find_package(PythonLibs REQUIRED) set(TorchPath /home/qzz/.conda/envs/bridge_research/lib/python3.8/site-packages/torch) message(STATUS TorchPath=${TorchPath}) list(APPEND CMAKE_PREFIX_PATH ${TorchPath}) find_package(Torch REQUIRED) set(TORCH_PYTHON_LIBRARIES "${TorchPath}/lib/libtorch_python.so") add_subdirectory(third_party/abseil-cpp) add_subdirectory(third_party/pybind11) add_library(t SHARED absl_simple_tests.h) target_link_libraries(t PUBLIC absl::base absl::algorithm absl::flags absl::optional absl::random_random absl::strings absl::str_format absl::time ${TORCH_LIBRARIES} ) target_include_directories(t PUBLIC ${TORCH_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR} third_party/abseil-cpp third_party/) add_executable(simple_tests main.cpp) target_link_libraries(simple_tests PUBLIC t)
absl_simple_tests.h
#include "absl/strings/str_cat.h" #ifndef SIMPLE_TESTS_ABSL_SIMPLE_TESTS_H #define SIMPLE_TESTS_ABSL_SIMPLE_TESTS_H std::string TestStrCat() { std::string s1; s1 = absl::StrCat("A string ", " another string", "yet another string"); return s1; } std::string TestStrAppend() { std::string s = "foo"; absl::StrAppend(&s, "123"); return s; } #endif //SIMPLE_TESTS_ABSL_SIMPLE_TESTS_H
main.cpp
#include <iostream> #include "absl_simple_tests.h" #include "torch/torch.h" int main() { auto s = TestStrCat(); std::cout << s << std::endl; s = TestStrAppend(); std::cout << s << std::endl; std::cout << torch::eye(3) << std::endl; return 0; }
解决方案
1. 修正ABI设置方式
LibTorch v2.0默认使用旧版C++ ABI(_GLIBCXX_USE_CXX11_ABI=0),但直接set(_GLIBCXX_USE_CXX11_ABI 0)不会将该定义传递给编译器和Abseil的编译过程。需要将其改为编译定义:
替换原CMake中的set(_GLIBCXX_USE_CXX11_ABI 0)为:
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
或者针对单个目标设置:
target_compile_definitions(t PUBLIC _GLIBCXX_USE_CXX11_ABI=0) target_compile_definitions(simple_tests PUBLIC _GLIBCXX_USE_CXX11_ABI=0)
确保该设置在add_subdirectory(third_party/abseil-cpp)之前,让Abseil使用相同的ABI编译。
2. 将头文件中的函数实现移至cpp文件
头文件中直接包含函数实现会导致每个引用该头文件的目标都编译一份代码,可能引发链接冲突或符号不一致。创建absl_simple_tests.cpp:
#include "absl_simple_tests.h" std::string TestStrCat() { std::string s1; s1 = absl::StrCat("A string ", " another string", "yet another string"); return s1; } std::string TestStrAppend() { std::string s = "foo"; absl::StrAppend(&s, "123"); return s; }
然后修改CMake中库的构建命令,将cpp文件加入:
add_library(t SHARED absl_simple_tests.cpp absl_simple_tests.h)
3. 确保CMake标准与依赖传递正确
确认ABSL_PROPAGATE_CXX_STD ON已开启,让Abseil继承项目的C++17标准。同时检查LibTorch的find_package(Torch REQUIRED)是否正确导入了其编译设置。
完成以上修改后,重新构建项目即可解决链接错误。
内容的提问来源于stack exchange,提问作者hanyuu1
相关产品推荐
相关产品推荐

