4、第一个配方:创建简单的Hello World配方、理解SRC_URI和do_compile
好,咱们终于要动手写第一个配方了。
说实话,我当年刚接触Yocto时,最头疼的就是不知道一个配方到底长什么样。文档里讲了一堆变量、任务、继承关系,但就是没人给我一个能跑起来的例子。所以这一章,咱们就直接从零开始,写一个最简单的Hello World配方。
4.1 配方文件长什么样?
一个Yocto配方,本质上就是一个.bb文件。它告诉BitBake三件事:
- 从哪里下载源码(SRC_URI)
- 怎么编译(do_compile)
- 怎么安装(do_install)
嗯,其实就这三步。你想想看,这不就跟咱们平时手动编译软件一样吗?下载源码包、解压、make、make install。Yocto只是把这个过程自动化了。
核心要点:配方 = 元数据 + 任务函数。元数据描述「是什么」,任务函数描述「怎么做」。
4.2 创建我们的第一个配方
先建个目录。我个人习惯把自定义配方放在meta-custom/recipes-example/hello/下面。这样一眼就能看出来是实验用的例子。
mkdir -p meta-custom/recipes-example/hello
cd meta-custom/recipes-example/hello
touch hello_1.0.bb
文件名hello_1.0.bb,1.0是版本号。Yocto会从文件名里自动解析出包名和版本,所以命名要规范。
打开这个文件,写入以下内容:
SUMMARY = "A simple Hello World program"
DESCRIPTION = "This recipe demonstrates the minimal Yocto recipe structure"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://hello.c"
S = "${WORKDIR}"
do_compile() {
${CC} ${CFLAGS} ${LDFLAGS} hello.c -o hello
}
do_install() {
install -d ${D}${bindir}
install -m 0755 hello ${D}${bindir}
}
别急着复制粘贴,咱们一行一行拆开看。
4.3 理解SRC_URI:源码从哪来?
SRC_URI是配方的灵魂。它告诉BitBake:「嘿,去这里拿源码!」
常见的SRC_URI写法有几种:
| 协议 | 示例 | 说明 |
|---|---|---|
| 本地文件 | file://hello.c |
从配方同目录或FILESPATH中找 |
| HTTP下载 | http://example.com/hello.tar.gz |
自动下载并解压 |
| Git仓库 | git://github.com/xxx/hello.git;branch=main |
克隆Git仓库 |
咱们这里用的是file://hello.c,意思是「在配方文件旁边找hello.c」。所以你还得创建一个hello.c文件放在同一个目录下。
小技巧:如果你用file://协议,Yocto默认会在${WORKDIR}里找到这些文件。但前提是它们必须放在配方的「files」子目录里,或者跟配方同级。我刚开始就栽在这个坑里——文件放错位置,编译时死活找不到。
创建hello.c:
#include <stdio.h>
int main() {
printf("Hello, Yocto!\n");
return 0;
}
简单吧?就一个打印语句。但别小看它,这个例子能帮你理解整个Yocto的构建流程。
4.4 理解do_compile:编译到底干了啥?
咱们再看do_compile()函数:
do_compile() {
${CC} ${CFLAGS} ${LDFLAGS} hello.c -o hello
}
这里用了几个变量:
${CC}:交叉编译器,比如arm-poky-linux-gnueabi-gcc${CFLAGS}:编译选项,包含目标架构的优化参数${LDFLAGS}:链接选项,确保链接正确的运行时库
说白了,Yocto帮你封装好了交叉编译环境。你不需要手动指定-march=armv7-a之类的参数,Yocto会根据你选的机器(MACHINE)自动配置。
注意:千万不要在do_compile里写死gcc!要用${CC}。我曾经见过有人直接写gcc hello.c -o hello,结果编译出来的是x86的二进制,放到ARM板上直接Segmentation Fault。血的教训。
4.5 知识体系图
下面这张图展示了本章的核心逻辑:一个配方从源码到安装的完整流程。
4.6 避坑指南:我踩过的三个坑
写第一个配方时,有几个地方特别容易出错。我当年都踩过,分享给你:
- 文件路径问题:
file://hello.c这个文件必须放在配方同目录,或者files/子目录下。我第一次写的时候把hello.c放到了meta-custom/根目录,结果BitBake报错说找不到文件。 - 权限问题:
do_install里一定要用install -m 0755设置可执行权限。我刚开始直接用了cp命令,结果编译出来的二进制没有执行权限,在目标板上跑不了。 - 变量拼写:
${CC}、${CFLAGS}这些变量名是大小写敏感的。我见过有人写成${cc},结果编译时用的还是宿主机的gcc,交叉编译完全没生效。
记住:Yocto的配方不是普通的Makefile。它运行在交叉编译环境下,所有路径、编译器、库都是为目标板定制的。写配方时,时刻问自己:「这个变量在目标板上会展开成什么?」
4.7 验证你的配方
配方写好了,怎么验证?用bitbake命令:
bitbake hello
如果一切顺利,你会看到BitBake依次执行do_fetch、do_unpack、do_compile、do_install、do_package等任务。最后在tmp/deploy/目录下生成hello的IPK或RPM包。
你也可以单独执行某个任务:
bitbake hello -c compile # 只编译
bitbake hello -c install # 只安装
bitbake hello -c clean # 清理
这个调试技巧很实用。我排查问题时,经常只跑-c compile,省得每次都从头开始。
好了,第一个配方就到这里。你亲手写了一个完整的Yocto配方,理解了SRC_URI怎么指定源码,do_compile怎么编译。这些基础打牢了,后面学复杂的配方就会轻松很多。
额外提示:如果你在编译时遇到ERROR: Nothing PROVIDES 'hello',八成是配方文件没被解析到。检查一下bblayers.conf里有没有添加meta-custom层。这个坑我见过不下十次了。
可可精品资料库