“Command not found”错误主因是PATH未包含工具链路径或工具链未安装,需用which和ls验证是否存在,再通过export临时添加或修改~/.bashrc并source生效。

交叉编译失败,八成不是代码问题,而是环境或路径没对上。 直接看报错类型,比翻源码更省时间。
报“Command not found”:PATH没设对或工具链压根没装
这不是GCC在报错,是shell在说“我根本没见过这个命令”。先确认你用的到底是不是交叉编译器:
- 运行
which arm-linux-gnueabihf-gcc或which aarch64-linux-gnu-gcc—— 如果空输出,说明PATH里没包含工具链的bin目录 - 检查安装路径是否存在:
ls /opt/gcc-linaro-*/bin/arm-linux-gnueabihf-gcc或ls /usr/bin/aarch64-linux-gnu-gcc* - 临时加PATH:
export PATH=$PATH:/opt/gcc-linaro-11.2.1-2021.10-x86_64_arm-linux-gnueabihf/bin - 永久生效别只改
~/.bashrc就完事——改完必须source ~/.bashrc,否则新开终端还是老样子 - Ubuntu用apt装的(如
gcc-aarch64-linux-gnu),命令名带版本号,得用aarch64-linux-gnu-gcc-10,不是aarch64-linux-gnu-gcc
报“undefined reference to 'xxx'”:链接时缺库,不是没写函数
编译过了,链接挂了。说明声明和调用都有,但目标文件或库没进链接阶段:
- 检查是否漏传
.c文件:gcc -o app main.c util.c比gcc -o app main.c多一个util.c,就可能崩在这里 - 用了POSIX线程?补
-lpthread;用了数学函数?补-lm;用了自定义库?确认-L/path/to/lib -lmylib都写了,且libmylib.so真在那个路径下 - 交叉环境下,宿主机的
/usr/lib/libm.so不能直接链——得用工具链自带的,或指定--sysroot指向目标系统根目录 - 如果看到
skipping incompatible /xxx/libxxx.so,说明你塞进去的是x86库,不是ARM版
CMake识别不到编译器:CC/CXX环境变量或toolchain文件失效
CMake不看PATH,它依赖CC和CXX环境变量,或显式指定的toolchain文件:
- 运行
echo $CC,如果不是arm-linux-gnueabihf-gcc之类,CMake就默认用本地gcc - 别在
~/.bashrc里全局设CC=...——不同项目用不同工具链时会冲突;改用项目级脚本:export CC=arm-linux-gnueabihf-gcc && cmake .. - 用toolchain文件更可靠:新建
arm-toolchain.cmake,写入set(CMAKE_SYSTEM_NAME Linux)、set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc),然后cmake -DCMAKE_TOOLCHAIN_FILE=arm-toolchain.cmake .. - 如果CMake报
The C compiler identification is unknown,大概率是arm-linux-gnueabihf-gcc --version执行失败——手动跑一遍,看是不是缺LD_LIBRARY_PATH或动态库
头文件或库找不到:-I/-L路径没生效,或预处理路径不对
报fatal error: xxx.h: No such file or directory,不等于头文件不存在,而是GCC没去对地方找:
- 用
echo 'void f(){}' | arm-linux-gnueabihf-gcc -E -v - 2>&1 | grep "search starts"查工具链默认include路径,确认你要的头文件是否在里面 - 自己加的
-I/path/to/headers,要确保/path/to/headers/xxx.h真存在;注意路径不要多写/或少写/,Linux下/inc和/inc/是两个路径 - 链接时报
cannot find -lxxx,用arm-linux-gnueabihf-gcc -print-search-dirs看它查哪些lib路径,再用find /opt/gcc-linaro-*/arm-linux-gnueabihf/libc -name "libxxx.so*"手动确认 - 交叉编译时慎用
-I/usr/include——那是宿主机头文件,类型定义和ABI可能跟目标平台不兼容
最常被忽略的一点:交叉编译器本身依赖宿主机的glibc或动态库,arm-linux-gnueabihf-gcc 运行时报“no such file or directory”,未必是命令不存在,可能是它自己的解释器(如/lib64/ld-linux-x86-64.so.2)缺失——这时候得装libc6-dev-amd64-cross之类的配套包,而不是继续折腾PATH。


















