最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
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(不是ARM或Generic) -
CMAKE_SYSTEM_PROCESSOR根据目标设为arm(ARMv7)、armv7或aarch64(ARM64),大小写敏感,不能写成ARM - 如果用的是
arm-linux-gnueabihf-工具链,CMAKE_SYSTEM_PROCESSOR写arm;如果是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_LIBRARY和CMAKE_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,或者文件里有语法错误(比如少了个右括号)。