跨编译aarch64时GLIBC版本不匹配问题及CMake配置求助
交叉编译aarch64程序时GLIBC版本不匹配问题
我刚接触C++应用开发,需要将程序交叉编译到aarch64架构的目标平台。目标设备运行Ubuntu 18.04,之前在Ubuntu 18.04的编译笔记本上编译出的程序能正常运行,但切换到Ubuntu 22.04的笔记本编译(其他配置完全不变)后,生成的二进制文件链接了错误版本的glibc。
我不明白编译主机的操作系统为什么会影响结果——我已经指定了目标设备的rootfs目录(见下方CMakeLists.txt),为什么还会调用编译主机的文件?目标rootfs里的glibc版本是正确的。
当前CMakeLists.txt配置
cmake_minimum_required(VERSION 3.21) project(cross_test) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc) set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++) set(CMAKE_FIND_ROOT_PATH /home/riz/testing/jetson_top_r32.7.2/Linux_for_Tegra/rootfs) set(SOURCE_FILES main.cpp) add_executable(${PROJECT_NAME} ${SOURCE_FILES})
目标设备上的报错信息
linux:~$ /tmp/cross_test /tmp/cross_test: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /tmp/cross_test)
问题原因
Ubuntu 22.04自带的aarch64-linux-gnu-gcc交叉编译器是基于主机高版本glibc构建的,仅设置CMAKE_FIND_ROOT_PATH不足以覆盖CMake默认的查找逻辑——它仍可能优先使用主机系统的头文件和库,导致最终二进制依赖了主机的高版本GLIBC符号。
解决配置
需要强制CMake优先使用目标rootfs中的资源,同时给交叉编译器明确指定目标系统的根文件系统路径:
1. 调整CMake查找策略
添加以下配置,让CMake完全跳过主机系统路径,只在目标rootfs中查找依赖:
# 禁止在主机系统查找可执行程序 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # 仅在目标rootfs中查找库、头文件和包 set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
2. 给编译器指定sysroot参数
交叉编译器需要明确知道目标系统的根文件系统位置,直接在编译器配置中添加--sysroot参数:
set(CMAKE_C_COMPILER "/usr/bin/aarch64-linux-gnu-gcc") set(CMAKE_C_COMPILER_TARGET "aarch64-linux-gnu") set(CMAKE_C_FLAGS "--sysroot=${CMAKE_FIND_ROOT_PATH} ${CMAKE_C_FLAGS}") set(CMAKE_CXX_COMPILER "/usr/bin/aarch64-linux-gnu-g++") set(CMAKE_CXX_COMPILER_TARGET "aarch64-linux-gnu") set(CMAKE_CXX_FLAGS "--sysroot=${CMAKE_FIND_ROOT_PATH} ${CMAKE_CXX_FLAGS}")
3. 完整的CMakeLists.txt示例
cmake_minimum_required(VERSION 3.21) project(cross_test) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) set(CMAKE_FIND_ROOT_PATH /home/riz/testing/jetson_top_r32.7.2/Linux_for_Tegra/rootfs) # 强制优先查找目标rootfs中的资源 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) # 配置交叉编译器并指定sysroot set(CMAKE_C_COMPILER "/usr/bin/aarch64-linux-gnu-gcc") set(CMAKE_C_COMPILER_TARGET "aarch64-linux-gnu") set(CMAKE_C_FLAGS "--sysroot=${CMAKE_FIND_ROOT_PATH} ${CMAKE_C_FLAGS}") set(CMAKE_CXX_COMPILER "/usr/bin/aarch64-linux-gnu-g++") set(CMAKE_CXX_COMPILER_TARGET "aarch64-linux-gnu") set(CMAKE_CXX_FLAGS "--sysroot=${CMAKE_FIND_ROOT_PATH} ${CMAKE_CXX_FLAGS}") set(SOURCE_FILES main.cpp) add_executable(${PROJECT_NAME} ${SOURCE_FILES})
额外注意事项
- 确保目标rootfs中的glibc、系统头文件等依赖完整无缺失
- 如果程序依赖第三方库,必须使用针对aarch64架构、基于目标系统GLIBC版本编译的库文件,避免再次出现版本不兼容问题
内容的提问来源于stack exchange,提问作者riz94107
相关产品推荐
相关产品推荐

