You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CMake链接git子模块spdlog静态库到.so共享库报重定位错误

问题根因

报错的核心原因是:你链接到Engine共享库(.so)的spdlog静态库,编译时没有开启位置无关代码(-fPIC)选项。
x86_64 Linux平台下,所有要被链接进共享对象的目标文件/静态库,必须使用-fPIC参数编译生成位置无关代码,否则链接阶段就会抛出你看到的R_X86_64_TPOFF32重定位错误。你直接通过add_subdirectory引入spdlog时,spdlog默认编译的静态库是为可执行文件链接准备的,默认未开启PIC选项,不满足共享库的链接要求。

解决方案

二选一即可,优先选第一种,符合spdlog官方推荐的静态使用方式。

方案1:编译spdlog静态库时开启PIC(推荐)

修改Engine目录下的CMakeLists.txt,在引入spdlog子目录前,开启spdlog的PIC编译配置:

message(STATUS "BUILD Engine shared library File")

# 强制spdlog静态库开启PIC编译,适配共享库链接要求
set(SPDLOG_ENABLE_PIC ON CACHE BOOL "Build spdlog with position independent code" FORCE)
add_subdirectory(spdlog)

add_library(Engine SHARED Log.cpp Log.h)
target_include_directories(Engine
          INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
          )

target_link_libraries(Engine PUBLIC spdlog)

注意:把spdlog的链接权限改成PUBLIC,这样依赖Engine的可执行目标会自动继承spdlog的头文件路径,不需要你手动配置spdlog的include目录。

方案2:将spdlog编译为共享库

如果你不需要静态链接spdlog,可以直接把spdlog编译为动态库,天然满足PIC要求:
在add_subdirectory(spdlog)前添加配置:

set(SPDLOG_BUILD_SHARED ON CACHE BOOL "Build spdlog as shared library" FORCE)

这种方式的缺点是部署时需要额外携带spdlog的.so文件,不符合官方静态使用的推荐。

额外配置优化建议

你现有CMake配置存在几处冗余/不规范点,可以顺手调整:

  • 已经通过set(CMAKE_CXX_STANDARD 17)配置了C++标准,不需要在CMAKE_CXX_FLAGS里重复加-std=c++17,重复配置可能跨编译器时出现兼容问题
  • CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS是Windows平台专属配置,在Linux下编译.so完全无效,可以加平台判断包裹,避免无效配置
  • 不需要手动为Engine添加spdlog的include路径,通过target_link_libraries链接spdlog时,CMake会自动传递spdlog配置的头文件搜索路径,手动硬编码路径在spdlog版本更新后容易出现路径不匹配问题。

修改完配置后,建议先删除整个build目录重新编译,避免旧的无PIC的spdlog静态库缓存导致报错复现。


内容的提问来源于stack exchange,提问作者miyoku

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 04:21:34