使用Sysroot基于Modern CMake交叉编译AArch64时libm.so查找错误解决
解决AArch64交叉编译中libm.so软链接导致的构建失败问题
问题根源
sysroot内的libm.so是指向内部相对路径的软链接(通常指向libm.so.6),交叉编译时CMake的find_library解析软链接后,生成的路径无法被交叉编译器正确识别,最终导致链接阶段失败。
工具链文件修改方案
在aarch64-toolchain.cmake中添加以下配置,无需改动项目或sysroot,同时兼容主机编译与交叉编译:
1. 优先查找实际库文件
调整库查找后缀的优先级,让CMake优先识别带版本号的实际库文件(而非软链接),同时限制库查找范围仅在sysroot内:
# 仅针对AArch64交叉编译生效 if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") # 优先查找带版本号的实际库文件,最后再找.so软链接 set(CMAKE_FIND_LIBRARY_SUFFIXES ".so.6" ".so.1" ".so") # 强制仅在sysroot内查找库,避免主机库干扰 set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # 替换为你的ubuntu-focal-arm64 sysroot实际路径 set(CMAKE_SYSROOT "/path/to/ubuntu-focal-arm64-sysroot") endif()
2. 强制解析软链接(可选,更彻底)
如果上述方法无效,可自定义find_library逻辑,强制将找到的软链接解析为实际文件路径:
function(find_library) # 调用原生CMake find_library逻辑 _find_library(${ARGV}) # 若找到的是软链接,解析到实际目标文件 if(${ARGV0}) get_filename_component(LIB_REAL_PATH ${${ARGV0}} REALPATH) set(${ARGV0} ${LIB_REAL_PATH} PARENT_SCOPE) endif() endfunction()
3. 兼容主机编译
在工具链文件开头添加条件判断,确保仅交叉编译时启用上述配置:
# 仅当目标架构与主机架构不同时,启用交叉编译配置 if(NOT CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL CMAKE_SYSTEM_PROCESSOR) # 放入上述交叉编译相关配置 endif()
验证步骤
- 交叉编译验证:清理构建目录后执行
rm -rf build && mkdir build && cd build cmake .. -DCMAKE_TOOLCHAIN_FILE=../aarch64-toolchain.cmake -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=aarch64 make - 主机编译验证:直接执行
cmake .. && make,确认可正常生成主机可执行文件
内容的提问来源于stack exchange,提问作者Xaldew
相关产品推荐
相关产品推荐

