CMAKE_SYSTEM_NAME必须设为Linux,CMAKE_SYSTEM_PROCESSOR须严格匹配目标架构(如aarch64),CMAKE_SYSROOT与浮点ABI需一致,且CMAKE_FIND_ROOT_PATH_MODE_PROGRAM设为NEVER、LIBRARY和INCLUDE设为ONLY,确保find_package等查找完全基于目标平台。

CMAKE_SYSTEM_NAME 必须设为 Linux,不是 ARM 或 Generic;漏掉这行,CMake 会默认按宿主机系统找库,后续所有 find_package() 都会失败。
CMAKE_SYSTEM_PROCESSOR 要和目标 CPU 架构严格匹配
- 树莓派 4/5、Jetson、大部分现代 ARM 板用的是
aarch64,不是arm - 老款 Cortex-A9 设备(如某些工控板)才用
arm或armv7 - 错配会导致
find_library()搜索路径错误,比如去lib/找库却该去lib/aarch64-linux-gnu/
示例:
树莓派 5 正确写法:set(CMAKE_SYSTEM_PROCESSOR aarch64)
旧 ARMv7 板正确写法:set(CMAKE_SYSTEM_PROCESSOR armv7)
立即学习“C++免费学习笔记(深入)”;
别依赖工具链前缀自动推断——CMake 不会从 aarch64-linux-gnu-g++ 里提取 aarch64 填到 CMAKE_SYSTEM_PROCESSOR,必须显式设置。
CMAKE_SYSROOT 和 -mfloat-abi 必须一致
常见报错:undefined reference to `__aeabi_dadd'
根源:sysroot 是 gnueabihf 的,但编译器用了 gnueabi 工具链,或没加 -mfloat-abi=hard
要确保三者统一:
- 工具链名:如
aarch64-linux-gnu-g++(隐含 hard-float) -
CMAKE_SYSROOT路径下有usr/lib/aarch64-linux-gnu/(不是arm-linux-gnueabi/) -
CMAKE_CXX_FLAGS包含-mfloat-abi=hard(对aarch64是默认,但显式写上更安全)
如果 sysroot 是自己拷贝的(比如从目标设备 rsync 过来),检查里面是否有 libstdc++.so,运行 file libstdc++.so 看是否标着 AArch64 和 hard-float。
CMAKE_FIND_ROOT_PATH<em>MODE</em>* 控制查找行为,不能全设成 ONLY
最容易被忽略的坑是:
-
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM设成ONLY→ CMake 会去 sysroot 里找pkg-config,但它在宿主机上 -
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY和INCLUDE必须是ONLY,否则find_package(OpenCV)可能混入 x86 头文件
推荐配置:
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
CMAKE_FIND_ROOT_PATH 应指向 sysroot 根目录(如 /opt/sysroot-aarch64),不是工具链安装目录。
交叉编译不是“换两个编译器路径就行”,关键在于让 CMake 完全切换到目标平台视角——它得相信自己正在一台 ARM Linux 上运行。任何一处变量没对齐,find_package() 就会悄悄回退到宿主机路径,链接时才发现找不到符号。


















