一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

C++如何配置CMake进行交叉编译 ARM开发

时间:2026-07-10 10:28:03 编辑:袖梨 来源:一聚教程网

toolchain文件必须显式设置CMAKE_SYSTEM_NAME和CMAKE_SYSTEM_PROCESSOR,否则CMake不进入交叉编译模式,导致CMAKE_FIND_ROOT_PATH_MODE_*等关键行为失效,find_package会错误链接宿主机库而引发编译或链接失败。

toolchain file 必须显式设置 CMAKE_SYSTEM_NAME 和 CMAKE_SYSTEM_PROCESSOR

不设这两个变量,CMake 就不会切换到交叉编译模式,CMAKE_FIND_ROOT_PATH_MODE_LIBRARY 等后续行为全失效。常见错误是只写 CMAKE_CXX_COMPILER,结果 find_package(Threads) 还是去宿主机找 libpthread.so,链接时直接失败。

正确做法是:在 toolchain 文件里固定写死:

  • CMAKE_SYSTEM_NAME 必须为 Linux(不是 ARMGeneric
  • CMAKE_SYSTEM_PROCESSOR 根据目标设为 arm(ARMv7)、armv7aarch64(ARM64),大小写敏感,不能写成 ARM
  • 如果用的是 arm-linux-gnueabihf- 工具链,CMAKE_SYSTEM_PROCESSORarm;如果是 aarch64-linux-gnu-,就写 aarch64

CMAKE_SYSROOT 和编译器 ABI 必须严格匹配

报错 undefined reference to `__aeabi_dadd'fatal error: bits/libc-header-start.h: No such file or directory,基本都是这里出问题。

三个地方必须一致:

立即学习“C++免费学习笔记(深入)”;

  • 工具链前缀:比如 arm-linux-gnueabihf-g++ 中的 gnueabihf
  • CMAKE_SYSROOT 路径下必须包含对应 ABI 的库子目录,例如 /usr/lib/arm-linux-gnueabihf//usr/lib/aarch64-linux-gnu/
  • CMAKE_CXX_FLAGS 里要加 -mfloat-abi=hard(对应 gnueabihf)或 -mfloat-abi=softfp(对应 gnueabi),不能靠编译器默认

Debian/Ubuntu 上装的 gcc-arm-linux-gnueabihf 默认 sysroot 在 /usr/arm-linux-gnueabihf/,路径不对就找不到头文件。

find_package() 查不到库?检查 CMAKE_FIND_ROOT_PATH_MODE_* 设置

find_package(OpenSSL) 找到的是宿主机版本,说明路径隔离没生效。根本原因是 CMake 不知道该“只查目标平台”还是“也查宿主机”。

必须显式控制查找范围:

  • CMAKE_FIND_ROOT_PATH 设为 CMAKE_SYSROOT(例如 /usr/arm-linux-gnueabihf
  • CMAKE_FIND_ROOT_PATH_MODE_PROGRAM 设为 NEVER(不查宿主机可执行文件)
  • CMAKE_FIND_ROOT_PATH_MODE_LIBRARYCMAKE_FIND_ROOT_PATH_MODE_INCLUDE 都设为 ONLY

漏掉任意一个,find_library 就可能混用宿主机的 .so 和目标平台的头文件,编译通过、链接失败。

验证 toolchain 是否真正生效,别等 build 失败再查

运行完 cmake -DCMAKE_TOOLCHAIN_FILE=xxx.cmake -S . -B build 后,立刻检查配置是否被读取:

cmake -LH -N build | grep -E "(CMAKE_SYSTEM|CMAKE_CXX_COMPILER|CMAKE_SYSROOT)"

输出里必须看到:

  • CMAKE_SYSTEM_PROCESSOR:STRING=arm(或 aarch64
  • CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/arm-linux-gnueabihf-g++
  • CMAKE_SYSROOT:PATH=/usr/arm-linux-gnueabihf

如果 CMAKE_SYSTEM_PROCESSOR 是空或显示 x86_64,说明 toolchain 文件压根没加载——可能是路径写错、CMake 版本低于 3.1,或者文件里有语法错误(比如少了个右括号)。

热门栏目