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

Android JNI项目中部分文件链接spdlog失败问题求助

链接错误排查:Android JNI项目spdlog符号未定义问题

问题概述

开发Android JNI项目时,采用CMake构建,分为静态库NativeUtils和主动态库drivermonitor,依赖spdlog日志库。NativeUtils中部分源文件调用spdlog::info等函数时出现链接错误,提示spdlog相关符号未定义,但同库内其他文件无此问题。

链接错误信息

: && /home/kartik/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=aarch64-none-linux-android26 --sysroot=/home/kartik/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security   -fno-limit-debug-info  -static-libstdc++ -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--fatal-warnings -Wl,--gc-sections -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,libdrivermonitor.so -o /home/kartik/Projects/DriverMonitor/service/build/intermediates/cxx/Debug/3n3s6c4k/obj/arm64-v8a/libdrivermonitor.so CMakeFiles/drivermonitor.dir/src/AiProcessor.cpp.o CMakeFiles/drivermonitor.dir/src/DriverMonitor.cpp.o CMakeFiles/drivermonitor.dir/src/DriverMonitorNative.cpp.o CMakeFiles/drivermonitor.dir/src/FrameCounter.cpp.o CMakeFiles/drivermonitor.dir/src/NetworkWrapper.cpp.o CMakeFiles/drivermonitor.dir/src/PreProcess.cpp.o CMakeFiles/drivermonitor.dir/test/NativePreProc.cpp.o  deps/NativeUtils/libNativeUtils.a  /home/kartik/Projects/DriverMonitor/deps/Snpe/lib/arm64-v8a/libSNPE.so  /home/kartik/Projects/DriverMonitor/deps/fastcv/lib/arm64-v8a/libfastcv.a  /home/kartik/Projects/DriverMonitor/deps/Snpe/lib/arm64-v8a/libc++_shared.so  _deps/fmt-build/libfmtd.a  _deps/spdlog-build/libspdlogd.a  /home/kartik/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/26/liblog.so  /home/kartik/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/26/libandroid.so  /home/kartik/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/26/libmediandk.so  /home/kartik/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/26/libjnigraphics.so  -pthread  -llog  -lc++_shared  /home/kartik/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/26/liblog.so  -latomic -lm && :

ld: error: undefined symbol: spdlog::details::log_msg::log_msg(spdlog::source_loc, fmt::v10::basic_string_view<char>, spdlog::level::level_enum, fmt::v10::basic_string_view<char>)
>>> referenced by logger.h:134 (_deps/spdlog-src/include/spdlog/logger.h:134)
>>>               AImageWrapper.cpp.o:(spdlog::logger::log(spdlog::source_loc, spdlog::level::level_enum, fmt::v10::basic_string_view<char>)) in archive deps/NativeUtils/libNativeUtils.a

各模块CMake配置

依赖模块CMakeLists.txt

cmake_minimum_required(VERSION 3.22)

project(SupportLibs)

find_library(native-media mediandk)
find_library(native-log log)
find_library(native-trace android)
find_library(native-graphics jnigraphics)
include(FetchContent)
FetchContent_Declare(fmt
        GIT_REPOSITORY https://github.com/fmtlib/fmt
        GIT_TAG 10.0.0)
FetchContent_Declare(spdlog
        GIT_REPOSITORY https://github.com/gabime/spdlog
        GIT_TAG v1.12.0)
FetchContent_MakeAvailable(fmt spdlog)

add_subdirectory(Snpe)
add_subdirectory(fastcv)
add_subdirectory(NativeUtils)

NativeUtils模块CMakeLists.txt

cmake_minimum_required(VERSION 3.22)

project(NativeUtils)

file(GLOB sources src/*.cpp)
file(GLOB headers include/*.hpp)

add_library(NativeUtils STATIC "${sources}" "${headers}")
print_list("${sources}")
target_include_directories(NativeUtils PUBLIC inc)
target_link_libraries(NativeUtils PUBLIC snpe c++_shared)
target_link_libraries(NativeUtils PRIVATE ${native-log} fmt::fmt spdlog::spdlog fastcv)
target_compile_features(NativeUtils PRIVATE cxx_std_17)

主库drivermonitor的CMakeLists.txt

cmake_minimum_required(VERSION 3.22)
project(DriverMonitor CXX)

macro(print_list)
    foreach(arg ${ARGV})
        message("  ${arg}")
    endforeach()
endmacro()

set(distribution_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../deps)

add_subdirectory(${distribution_DIR} ${CMAKE_CURRENT_BINARY_DIR}/deps)
file(GLOB headers inc/drivermonitor/*.h)
file(GLOB sources src/*.cpp test/*.cpp)
add_library(drivermonitor SHARED "${headers}" "${sources}")
target_compile_features(drivermonitor PRIVATE cxx_std_17)
target_include_directories(drivermonitor PRIVATE inc)
target_link_libraries(
        drivermonitor
        PRIVATE
        NativeUtils
        snpe
        fastcv
        c++shared
        fmt::fmt
        spdlog::spdlog
        ${native-log}
        ${native-trace}
        ${native-media}
        ${native-graphics}
)

排查与解决方法

1. 调整依赖可见性

NativeUtils中使用PRIVATE链接spdlog和fmt,导致主库drivermonitor无法自动继承这些依赖的链接顺序。将NativeUtils的链接配置改为PUBLIC,CMake会自动处理依赖库的链接顺序,确保spdlog在NativeUtils之后被链接,让链接器能正确找到符号:

# 修改NativeUtils的target_link_libraries
target_link_libraries(NativeUtils PRIVATE ${native-log} fastcv)
target_link_libraries(NativeUtils PUBLIC snpe c++_shared fmt::fmt spdlog::spdlog)

2. 检查fmt与spdlog版本兼容性

当前使用fmt 10.0.0和spdlog 1.12.0,spdlog 1.12.0发布时fmt 10尚未正式推出,存在API不兼容问题(如错误中出现的fmt::v10::basic_string_view可能未被spdlog 1.12.0支持)。将fmt版本降级到与spdlog 1.12.0兼容的9.x版本(如9.1.0):

FetchContent_Declare(fmt
        GIT_REPOSITORY https://github.com/fmtlib/fmt
        GIT_TAG 9.1.0)

3. 修正头文件路径

NativeUtils的target_include_directories指定了PUBLIC inc,但实际头文件放在include目录,路径不匹配可能导致部分源文件未正确包含spdlog头文件,编译出不匹配的符号。修正路径:

target_include_directories(NativeUtils PUBLIC include)

4. 确认链接顺序

如果上述方法无效,手动调整主库drivermonitor的链接顺序,将spdlog和fmt放在NativeUtils之后,确保链接器处理NativeUtils的未定义符号时,能从后续的spdlog库中找到对应实现:

target_link_libraries(
        drivermonitor
        PRIVATE
        snpe
        fastcv
        c++shared
        ${native-log}
        ${native-trace}
        ${native-media}
        ${native-graphics}
        NativeUtils
        fmt::fmt
        spdlog::spdlog
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:15:54