引言
1. 前言:由于近期项目需要,我被安排负责开发基于Yocto的Qt桌面应用程序。在Yocto项目下构建嵌入式Linux的过程中,我遇到了诸多挑战,从环境配置到编译错误,每一步都充满了不确定性。在历经各种艰难终于成功构建后,我深知对于初学者来说这个过程有多么不易。为此,我决定将整个构建过程记录下来,分享遇到的问题和解决方案,希望能让初次接触Yocto的开发者少走弯路,构建过程更加顺利。
-
Yocto项目简介及其在嵌入式领域的重要性
Yocto Project是一个开源的嵌入式Linux构建系统,它不是一个现成的Linux发行版,而是一个让你自己制作Linux发行版的工具集。
Yocto解决了嵌入式开发的根本矛盾:标准化生产与个性化定制。它让开发者能够在统一的框架下,为特定硬件和特定应用构建最合适的Linux系统。 -
个人学习Yocto的动机
最初接手Yocto确实是出于项目安排的客观原因,但随着深入了解,我不仅被它强大的定制能力所折服,更被它在嵌入式领域的巨大价值深深震撼。 -
本文能为读者解决什么问题
对于刚接触Yocto的开发者,本文将从环境搭建、配方(Recipe)编写到常见构建错误的排查,手把手带你完成第一个镜像的构建。你将获得一条清晰的入门路径,彻底弄清BitBake的工作流程,掌握解决依赖缺失和配方解析失败这些典型难题的方法。
编译环境说明
2.软硬件环境
2.1 硬件环境
- Yocto项目构建嵌入式Linux镜像是在Ubuntu Linux系统下进行的,建议你使用Ubuntu 16.04以上的版本,我这里是使用的Ubuntu 20.04 LTS版本。
- 16GB内存及以上,使Ubuntu Linux系统有足够的内存用于构建镜像。
- 80G的磁盘空间。
2.2 软件环境
- 宿主机完整的构建包清单
核心编译工具集:gcc, make, build-essential,
构建系统工具:make, gawk, diffstat, chrpath,
Python运行时环境:python3, python3-pip, python3-pexpect, python3-jinja2, python3-subunit, python3-git,
源码获取工具:git, wget,
压缩解压工具集:xz-utils, unzip, zstd, liblz4-tool,
文档生成工具:texinfo,
网络测试工具:iputils-ping,
图形界面支持:libegl1-mesa, libsdl1.2-dev, mesa-common-dev, xterm,
系统工具:socat, cpio, debianutils,
代码质量工具:pylint3
提示:我在后面正式的构建中会用到上面的所有工具,新手不用担心,这里展示出来只是让大家有个初步的了解
- Yocto分支版本
这里我们选择Dunfell分支版本,这是一个长期支持(LTS)的稳定版本。对新手来说,它拥有最成熟稳定的生态,能最大可能的少踩坑。唯一的不足是它的官方支持已于2024年4月结束。
如果你希望使用仍处于官方支持周期内的稳定版本,可以选择Kirkstone。它作为更新的LTS版本,功能更丰富,但软件包体积也更大,这会导致构建所需的时间和磁盘空间显著增加。
构建过程全记录
3.Yocto构建实战
3.1 准备构建环境
- 安装工具集
我们打开系统中的Terminal,然后输入如下这一行指令来安装构建所必须的工具集。
sudo apt install gawk wget git diffstat unzip texinfo gcc build-essential chrpath socat
cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git
python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 xterm python3-subunit
mesa-common-dev zstd liblz4-tool -y
- 输入密码
提示:这里需要输入自己的用户登录密码,也就是开机后登录Ubuntu桌面时输入的密码。输入密码时,屏幕上不会有任何显示,这是正常的安全设计。
- 回车,开始安装工具集
这里,我们构建所必须的工具集就已经安装准备好了!
3.2 下载Yocto的Poky
提示:获取Poky,这是Yocto的核心框架。Poky包含了构建自定义Linux镜像所需的所有组件。
逐行输入如下三行指令来下载Poky。
$ git clone git://git.yoctoproject.org/poky
$ cd poky
$ git fetch --tags
这里,我们的Poky就已经成功下载好了。你也可以到文件目录中去查看验证。因为Git代码文件很多是隐藏的,需要点击右上角"☰"菜单来显示隐藏的文件。
3.3 选择对应的Yocto分支版本
如我们上面所说的,我们选择Dunfell版本。输入如下指令来进行指向。
git checkout -t origin/dunfell -b my-dunfell
3.4 初始化构建环境
输入如下指令来初始化编译环境。
source oe-init-build-env
这里,我们构建环境的初始化就已经完成了!
3.5 开始正式构建
提示:构建过程中,如果出现报错,我们需要立马停止构建,先解决完问题后,再继续构建。停止指令:Ctrl+C
输入如下指令开始进行构建。
bitbake core-image-sato
在构建过程中,你可能会在终端看到如下黄色警告信息,这是系统正在自动切换和配置可用的镜像源,不用担心。
提示:构建的过程肯定会出现不同的错误,如你在过程中出现错误,首先停止构建,然后看一看我下面的问题解决实录这一章节所写的,相信一定能帮到你。
3.6 构建完成
这时,我们可以在如下文件目录中看到已经构建完成的镜像文件了。
3.7 结果验证
执行如下指令,输入用户密码,该密码依然为之前安装工具集时所输入的自己的用户登录密码,启动 QEMU 虚拟机来运行你刚刚构建的 Yocto 系统镜像。
提示:在终端主机或者 ~/poky/build 层级输入这条指令均可。
runqemu qemux86-64
这里,我们的Yocto系统镜像就已经成功构建完成了!
问题解决实录
4. 踩坑记录与解决方案
注:有趣的是,当我为了准备本文而重新构建镜像时,却只遇到了"gcc内存不足"问题。之前困扰我的qemu-native和gcc-runtime问题并未复现。这正说明了Yocto构建的环境敏感性——你可能遇到不同的问题,但解决思路是相通的。我将在本章结尾附上构建过程中解决问题的方法论。
4.1 gcc编译内存不足
- 错误现象:g++: fatal error: Killed signal terminated program cc1plus
然后,我们顺着错误提示的文件目录,找到记录错误信息的日志。一般在日志的最后50行左右会显示错误信息,这里的错误信息如下:
g++: fatal error: Killed signal terminated program cc1plus
compilation terminated.
make[2]: *** [Source/CMakeFiles/CMakeLib.dir/build.make:1210: Source/CMakeFiles/CMakeLib.dir/cmGeneratorTarget.cxx.o] Error 1
make[2]: *** Deleting file 'Source/CMakeFiles/CMakeLib.dir/cmGeneratorTarget.cxx.o'
make[2]: *** Waiting for unfinished jobs....
make[2]: Leaving directory '/home/pinkbichon/poky/build/tmp/work/x86_64-linux/cmake-native/3.16.5-r0/build'
make[1]: *** [CMakeFiles/Makefile2:1864: Source/CMakeFiles/CMakeLib.dir/all] Error 2
make[1]: Leaving directory '/home/pinkbichon/poky/build/tmp/work/x86_64-linux/cmake-native/3.16.5-r0/build'
make: *** [Makefile:166: all] Error 2
ERROR: oe_runmake failed
WARNING: exit code 1 from a shell command.
ERROR: Execution of '/home/pinkbichon/poky/build/tmp/work/x86_64-linux/cmake-native/3.16.5-r0/temp/run.do_compile.631029' failed with exit code 1
-
根本原因:物理内存不足,
Killed signal terminated program cc1plus表示编译进程被系统强制终止了。cc1plus是g++的前端编译器,处理复杂C++代码时需要大量内存,物理内存不足时,依赖交换空间,交换空间不足或太慢,进程被OOM Killer终止。 -
解决方案:增加8GB交换空间然后优化并行编译。
逐行输入如下指令来修复此异常。
- 先增加交换空间到16GB
sudo swapoff /swapfile 2>/dev/null
sudo fallocate -l 16G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
free -h
- 调整配置
cd ~/poky/build
cat >> conf/local.conf << 'EOF'
BB_NUMBER_THREADS = "2"
PARALLEL_MAKE = "-j 2"
PARALLEL_MAKE_pn-cmake-native = "-j 1"
SELECTED_OPTIMIZATION = "-O1"
EOF
- 清理并重试
bitbake cmake-native -c cleansstate
bitbake cmake-native
cmake-native 编译成功了。
问题已修复,接下来,再次输入如下指令,继续进行主干构建流程。
bitbake core-image-sato
在构建过程中,每个人都可能遇到不同的错误。但掌握正确的排查思路,你就能顺利解决问题。以下是经过我实践验证的五步排查法:
1. 遇到错误信息不要慌,马上Ctrl+C停止构建。
2. 定位日志,提取关键信息。
3. 识别错误类型,匹配解决方案。
4. 找到错误的原因和解决方案,实施针对性修复。
5. 修复完成,重新开始主干流程的构建。
结语&加学习群
到这里,你已经成功构建出了自己的第一个Yocto镜像文件。相信在工作中遇到定制化需求时,你也能从容应对了。
我是粉色小比熊
- 一个待过大厂,混过外包,目前正在一家外企折腾的作死型前后端选手;
- 一个遇到新技术就流口水的全干软件工程师;
- 一个不咋正经的掘金作者;
- 一个喜欢旅游和摄像的视频菜鸟;
- 一个热衷自驾川西的业余改装菜鸟;
- 一个英语不太好偏偏又喜欢没事儿抖两句的口语选手;
如果你也对以下话题感兴趣:
- 前后端技术学习与成长
- 简历优化与面试技巧
- 视频拍摄与剪辑
- 英语学习交流
- 汽车改装与自驾游
点个赞加关注 欢迎私信我。 加油 努力成为大佬!