服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-10-22 简米科技 4,654 字 11 分钟阅读

虚拟机中uboot编译失败怎么办?,编译失败原因有哪些

导读虚拟机中uboot编译失败,最常见的原因不是代码本身,而是编译环境没配好——依赖库缺失、交叉编译工具链不对、磁盘或内存不足占了大头,按“环境—依赖—资源—工具链”的顺序排查,多数问题能在十分钟内解决,嵌入式开发中,很多人习惯在VMware或VirtualBox里搭Ubuntu虚拟机来编译U-Boot,省去双系统……

虚拟机中uboot编译失败,最常见的原因不是代码本身,而是编译环境没配好依赖库缺失、交叉编译工具链不对、磁盘或内存不足占了大头,按“环境依赖资源工具链”的顺序排查,多数问题能在十分钟内解决。

嵌入式开发中,很多人习惯在VMware或VirtualBox里搭Ubuntu虚拟机来编译U-Boot,省去双系统的麻烦,但虚拟机环境天然多了一层隔阂,编译失败时看到满屏报错,第一反应往往是代码有问题。绝大多数虚拟机场景下的编译失败,根源出在宿主环境与目标环境的差异上。

虚拟机uboot编译失败如何排查先分清是哪一类报错

报错信息是定位问题的唯一线索,面对一大段输出,不要急着复制全文去搜索,先看报错属于哪一类,不同类别的错误,解决路径完全不同。

最常见的三类报错特征

  • 缺少头文件或库文件(如fatal error: openssl/evp.h: No such file or directory、/usr/bin/ld: cannot find -lssl),指向依赖缺失,通常是Ubuntu基础包没装全。
  • 工具链问题(如arm-linux-gnueabihf-gcc: command not found、arm-none-eabi-gcc: No such file or directory),指向交叉编译器没有安装或未加入PATH。
  • 资源耗尽类(如virtual memory exhausted: Cannot allocate memory、No space left on device),指向虚拟机分配的内存、交换分区或磁盘空间不足。
报错类型 典型报错片段 第一排查方向
依赖缺失 No such file or directory 缺失哪个头文件/库,apt安装对应包
工具链缺失 command not found 检查交叉编译器是否安装、是否在PATH
内存不足 virtual memory exhausted 调大虚拟机内存,降低make并行度
磁盘不足 No space left on device 清理磁盘,扩容虚拟磁盘

先看Makefile配置和.config

如果你刚拿到一份开发板BSP包,直接执行make报错,先检查.config是否存在。U-Boot编译前必须先配置,没有.config就编译,一定会报错,常见配置命令是根据开发板型号在U-Boot根目录执行make xxx_defconfig,比如make stm32mp15_defconfig,如果你跳过了配置步骤,建议先回到这一步。

虚拟机里编译uboot报错Missing dependencies环境问题占大头

行业内有一个广泛共识:发生在虚拟机里的uboot编译失败,环境依赖问题占比最高,虚拟机通常是一个最小化安装或精简版的Ubuntu,桌面环境能跑起来,但编译工具链和开发库往往缺失严重。

U-Boot编译的基础依赖清单

执行以下命令安装基础依赖,U-Boot源码根目录下的README文件中也明确列出了要求:

sudo apt install bison flex make gcc swig python3-dev \
  libssl-dev libgcc1 libgcc-11-dev libncurses5-dev \
  pkg-config gawk device-tree-compiler

这里面有几个容易忽略的点:

  • swig:U-Boot从2018年之后的部分版本编译时需要swig生成Python绑定文件,缺失时报"swig" is not installed,解决方法是sudo apt install swig。
  • libssl-dev:编译mkimage工具时需要OpenSSL开发库,缺失时报openssl/evp.h找不到,安装libssl-dev即可。
  • python3-dev:部分较新版本U-Boot使用Python脚本处理配置,缺失时报Python.h: No such file or directory。
  • device-tree-compiler(dtc):编译设备树blob时需要,缺失时在scripts/dtc阶段报错。

安装完之后,删除之前编译产生的中间文件,重新开始:

make distclean
make <你的开发板_defconfig>
make -j4

32位库缺失是虚拟机特有的坑

如果你在64位Ubuntu虚拟机里编译一些老版本U-Boot,链接阶段可能报cannot find -lz或/usr/bin/ld: skipping incompatible /usr/lib/...,原因是老版本工具链需要32位兼容库,解决方式:

sudo dpkg --add-architecture i386
sudo apt update
sudo apt install libc6:i386 libncurses5:i386 libstdc++6:i386

另一个常见做法是关于libncurses,新版Ubuntu中libncurses5-dev可能找不到包,改用libncurses-dev安装即可。

交叉编译工具链的配置失误

如果你在编译前已经设置了交叉编译环境变量,但仍报command not found,常见原因是环境变量在超级用户下未生效:

sudo make -j4

sudo会重置环境变量,导致CROSS_COMPILE值失效。正确的做法是编译时显式指定交叉编译前缀,而不是依赖环境变量:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4

这里也顺便检查一下,arm-linux-gnueabihf-gcc是否真的已安装:

arm-linux-gnueabihf-gcc -v

如果提示未找到,执行:

sudo apt install gcc-arm-linux-gnueabihf

Ubuntu虚拟机编译u-boot总失败内存与磁盘是隐形杀手

如果依赖全装齐了、工具链也正常,但编译到一半虚拟机死机或报错,问题多半出在资源分配上。虚拟机不像物理机,内存和磁盘都是“借”来的,资源耗尽的表现形式更隐蔽。

内存不足导致的诡异编译中断

U-Boot编译本身不算吃资源,但当你使用高并行度编译时,虚拟机会瞬间吃掉大量内存,比如宿主机只有8GB内存,虚拟机分配了4GB,执行make -j16时,16个编译任务同时跑,内存直接爆掉,编译进程被系统OOM Killer杀掉,报错信息随机且无规律,可能出现在任意源文件上。

解决思路有两个方向:

  • 降低并行度:make -j2或make -j4,代价是编译时间变长,但稳定。
  • 加大虚拟机内存并增加交换分区:在VMware设置中把内存调到6GB以上,同时给虚拟机增加一个4GB的swap分区(注意,U-Boot编译对内存需求远小于内核,但如果同时开了IDE、浏览器和多个终端,情况就不一样了)。

磁盘空间不足的隐蔽表现

虚拟机磁盘空间不足时,报错可能不是“磁盘满”,而是链接阶段突然报Permission denied或Text file busy,这是因为临时文件写入失败,ld无法生成最终的可执行镜像。

检查磁盘空间:

df -h

如果使用率超过90%,清理编译缓存的临时文件,删除U-Boot目录下的.tmp目录和.o文件,或者直接make clean重新来过。

文件系统类型的坑:Windows共享目录编译

很多人在VMware里把U-Boot源码放在Windows宿主机共享文件夹(vmhgfs-fuse挂载)下编译,这种做法的出错率远高于本地磁盘。共享文件系统对符号链接和文件锁的支持不完善,编译过程中常出现未知错误,比如No rule to make target这类诡异报错。

可靠的解决办法:把源码拷贝到Ubuntu虚拟机的本地文件系统(比如~/workspace/)再编译,这个坑触碰过的人不少,属于虚拟机场景下的高频问题。

从失败日志到干净构建一套可复现的排查顺序

当报错信息比较模糊时,不要乱试,按下面这个顺序,每次改一个变量,逐步缩小范围:

记录完整的错误日志

执行编译时,把输出重定向到文件里:

make -j4 2>&1 | tee build.log

先用grep -i error build.log筛出错误行,定位第一条真正的错误,而不是最后一条,编译器的报错通常是连锁反应,第一条错误可能才是根因。

逐一排除环境变量、源码路径、并行度三类因素

  • 确保源码目录路径中不包含中文和空格,这个细节在Windows宿主机共享目录下尤其重要。
  • 尽量使用非root用户编译,但确认该用户的PATH和权限没问题。
  • 并行度从低到高逐个试:先make -j1确认能过,再逐步提升,排除内存瓶颈。

对比官方构建文档和板卡BSP要求

不同开发板的U-Boot编译要求差异很大,比如某些厂商提供的SDK要求特定的GCC版本,太新的gcc会导致编译报错,检查开发板资料中提到的工具链版本和U-Boot版本是否匹配,必要时切换到对应版本的工具链。

虚拟机编译uboot总是报错怎么办快问快答

Q:在虚拟机里编译U-Boot,老是报“make[1]: gcc: Command not found”,怎么解决?

A:这是gcc没有安装或没进PATH导致的,执行sudo apt install build-essential,安装完成后用gcc --version验证,如果你设置了CC=gcc的环境变量,也要确认它在当前shell中生效,部分用户习惯把环境变量写在~/.bashrc里,但新开的终端没执行source ~/.bashrc,环境变量自然不生效。

Q:U-Boot编译到一半显示“virtual memory exhausted: Cannot allocate memory”,但虚拟机内存显示还有剩余,为什么?

A:这是典型的进程数过多或单进程内存受限,检查虚拟机的交换分区是否配置,如果swap为0,可以在虚拟机内创建一个2GB的swap文件启用。ulimit -a查看进程虚拟内存限制,如果virtual memory那一项显示unlimited,直接降低make并行度即可。

Q:Windows宿主机+VMware虚拟机,U-Boot源码放在D盘共享文件夹里编译报错,但同样的源码拷贝到Ubuntu本地目录就没问题,是什么原因?

A:vmhgfs-fuse共享文件系统对某些文件操作的支持不完整,尤其对符号链接、权限位和文件锁处理存在差异,U-Boot编译过程中会创建大量符号链接和临时文件,在共享目录下容易触发异常行为,行业常见的建议是:将源码放置到虚拟机的ext4/xfs本地文件系统下编译,提升稳定性,如果你必须在共享目录下操作,使用cp -a完整保留权限地复制到本地再编译,成功后把产物拷贝回来。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱