Qt C++项目编译Android时出现__sendto_chk未定义符号链接错误
__sendto_chk未定义的解决方案 问题重现
使用arm64-v8a架构编译的libobd_scanner.a静态库链接到Qt Android项目时,出现链接错误:
error: undefined symbol: __sendto_chk
referenced by socket.h:72 (/home/misha/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/bits/fortify/socket.h:72)
connect.cpp.o:(OBD::OBDConnectNetwork::sendAllData()) in archive /usr/local/lib/libobd_scanner.a
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
仅包含库头文件时编译正常,实例化库对象时触发链接错误;Linux本地编译无问题,不含系统调用的测试库可正常编译。
解决方案
1. 确保静态库使用对应Android NDK编译
__sendto_chk是Android NDK中Fortify源码增强机制提供的函数,不能用Linux主机编译器编译ARM64架构的库,必须使用目标Android版本的NDK交叉编译工具链:
- 编译
libobd_scanner.a时,指定NDK的clang作为编译器,设置目标架构arm64-v8a和匹配的Android API级别(与Qt项目使用的API一致)。 - 如果编译库时启用了Fortify(默认开启),确保编译选项和Qt项目一致,比如
-D_FORTIFY_SOURCE=2;若临时测试,可添加-U_FORTIFY_SOURCE关闭Fortify。
2. 调整CMakeLists.txt的链接配置
给导入的静态库添加系统库依赖,确保链接时能找到__sendto_chk的实现:
修改导入库的属性,添加INTERFACE_LINK_LIBRARIES关联系统c库:
add_library(obd_scanner STATIC IMPORTED) set_target_properties(obd_scanner PROPERTIES IMPORTED_LOCATION /usr/local/lib/libobd_scanner.a INTERFACE_LINK_LIBRARIES c )
同时确认库的架构arm64-v8a和Qt Android编译的架构完全一致,避免架构不匹配。
3. 统一编译选项与NDK配置
在CMakeLists.txt中明确Android相关编译参数,确保和静态库的编译环境对齐:
if(ANDROID) # 指定NDK路径和目标参数 set(ANDROID_NDK /home/misha/Android/Sdk/ndk/25.1.8937393) set(ANDROID_ABI arm64-v8a) set(ANDROID_PLATFORM android-31) # 与静态库编译时的API级别一致 # 统一Fortify选项 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2") endif()
4. 修复find_package找不到库的问题
若想使用find_package(obd_scanner REQUIRED),需要:
- 为
libobd_scanner编写obd_scannerConfig.cmake配置文件,指定库的路径、头文件目录和依赖。 - 将配置文件所在目录添加到
CMAKE_PREFIX_PATH,让CMake能找到:set(CMAKE_PREFIX_PATH "/usr/local/lib/cmake/obd_scanner" ${CMAKE_PREFIX_PATH}) find_package(obd_scanner REQUIRED)
内容的提问来源于stack exchange,提问作者Misha Makovka

