4、Yocto源码获取:Repo初始化、manifest仓库选择、同步源码、分支切换、常见问题处理
源码获取,是整个Yocto构建流程的第一步。这一步要是没走对,后面全是白费功夫。我见过不少新手,上来就repo sync,结果同步到一半报错,或者同步完了发现分支不对,又得重来。
说白了,Yocto的源码管理,核心就是Google的Repo工具。它不直接管理代码,而是管理一堆Git仓库。你想想看,一个完整的Yocto BSP,动辄上百个Git仓库,一个个手动git clone,那得搞到猴年马月?Repo就是干这个的——它通过一个manifest清单文件,告诉你该拉哪些仓库、拉哪个分支、放到哪个目录。
核心逻辑: Repo + Manifest = 批量Git仓库管理方案。Manifest是“菜单”,Repo是“服务员”,你只需要告诉服务员你要哪个菜单(哪个XML文件),他就能帮你把菜(源码)全部端上来。
4.1 安装Repo工具
大多数Linux发行版不会预装Repo。你得手动装。我个人习惯把它放在~/bin目录下,这样不影响系统全局。
# 创建本地bin目录(如果不存在)
mkdir -p ~/bin
# 下载Repo脚本
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
# 赋予执行权限
chmod a+x ~/bin/repo
# 将~/bin加入PATH(建议写入~/.bashrc)
export PATH=$PATH:~/bin
小技巧: 国内网络环境,Google的源可能很慢。你可以用清华或中科大的镜像源:
# 使用清华镜像
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo
4.2 选择Manifest仓库
Manifest仓库,就是那个包含default.xml的Git仓库。Rockchip官方、第三方BSP厂商、甚至你自己公司,都可能维护着不同的Manifest。
以Rockchip官方Yocto BSP为例,常用的Manifest仓库有:
| Manifest仓库地址 | 适用平台 | 说明 |
|---|---|---|
https://github.com/rockchip-linux/repo.git |
RK3399 / RK3288 / RK3568 等 | Rockchip官方维护,分支对应不同Linux内核版本 |
https://github.com/radxa/manifests.git |
Radxa系列开发板 | 第三方厂商定制,通常包含更多板级配置 |
https://github.com/amarula/rockchip-manifests.git |
通用Rockchip平台 | Amarula社区维护,更新较快 |
嗯,这里要注意。Manifest仓库的分支决定了你拉取的BSP版本。比如Rockchip官方repo仓库,master分支可能对应最新的开发版,而linux-5.10分支对应稳定版。我在项目中遇到过,有人拉了master分支,结果编译到一半发现某个驱动接口变了,折腾了两天才定位到问题。
避坑指南: 选择Manifest仓库时,先确认它是否包含你目标芯片的machine配置。比如你要做RK3588,但Manifest里只有RK3399的配置,那后面编译时会直接报错。我曾经因为这个浪费了半天时间。
4.3 repo init 初始化
选好Manifest仓库后,就可以初始化了。命令格式如下:
# 基本格式
repo init -u <manifest仓库URL> -b <分支名> -m <manifest文件名>
# 示例:拉取Rockchip官方RK3568的Yocto BSP(基于Linux 5.10)
mkdir rk3568-yocto
cd rk3568-yocto
repo init -u https://github.com/rockchip-linux/repo.git -b linux-5.10 -m rockchip-yocto.xml
几个参数的含义:
-u:Manifest仓库的URL-b:指定仓库的分支(不是BSP的分支,是Manifest仓库本身的分支)-m:指定使用哪个XML文件。如果不指定,默认用default.xml
执行成功后,会在当前目录生成一个.repo隐藏目录。这个目录里包含了Manifest仓库的克隆和Repo的配置信息。你可以进去看看:
ls -la .repo/
# 你会看到 manifest.xml(指向实际manifest的软链接)
# manifests/(manifest仓库的完整克隆)
# repo/(repo工具自身的副本)
关键点: repo init 只是初始化了Repo环境,并没有下载任何BSP源码。它只下载了Manifest仓库本身。真正的源码下载,在下一步。
4.4 repo sync 同步源码
这是最耗时的一步。执行后,Repo会根据Manifest文件中的描述,逐个克隆或拉取所有Git仓库。
# 同步所有仓库(默认4个并发任务)
repo sync
# 如果你网络不错,可以增加并发数
repo sync -j8
# 如果中途断了,重新执行会自动断点续传
repo sync --force-sync
同步完成后,你会看到当前目录下出现了大量子目录。比如poky/、meta-openembedded/、meta-rockchip/、meta-qt5/等等。这些就是Yocto的各个layer。
为什么会这么慢?因为Yocto的源码量确实大。一个完整的Rockchip BSP,包括Poky核心层、OpenEmbedded层、Rockchip硬件适配层、Qt图形层等,加起来可能有几十个Git仓库,总大小超过10GB。我第一次同步时,用了将近两个小时。
加速技巧:
- 使用国内镜像源(如清华、中科大)替换Google的Git源
- 如果公司有GitLab,可以先把Manifest和所有子仓库镜像到内网
- 用
repo sync -c只同步当前分支,不同步所有远程分支,能省不少时间
4.5 分支切换
同步完成后,你可能需要切换到特定的开发分支。比如官方BSP默认拉取了linux-5.10分支,但你想试试linux-6.1的实验性分支。
分支切换有两种方式:
方式一:重新init + sync(推荐)
# 重新初始化,指定新分支
repo init -u https://github.com/rockchip-linux/repo.git -b linux-6.1 -m rockchip-yocto.xml
# 强制同步,覆盖本地修改
repo sync --force-sync
方式二:手动切换(不推荐,容易漏仓库)
# 遍历所有仓库切换分支
repo forall -c 'git checkout linux-6.1'
我个人强烈建议用方式一。为什么?因为Manifest文件里可能对不同仓库指定了不同的分支或提交ID。手动切换很容易漏掉某个仓库,导致编译时出现莫名其妙的版本不匹配错误。我在项目中吃过这个亏,后来就老老实实重新init了。
注意: 如果你在某个子仓库里有未提交的修改,repo sync --force-sync 会强制覆盖。建议先 repo status 检查一下本地状态,或者用 git stash 暂存修改。
4.6 常见问题处理
源码获取阶段,我遇到过的坑不少。挑几个典型的说说:
| 问题现象 | 原因 | 解决方法 |
|---|---|---|
fatal: unable to access '...' |
网络不通,或Git服务器被墙 | 换镜像源,或配置代理 |
repo sync 卡在 99% |
某个子仓库的tag或commit不存在 | 按 Ctrl+C 中断,检查Manifest中指定的commit是否有效 |
error: revision refs/tags/xxx not found |
Manifest中指定的tag在远程仓库中不存在 | 联系BSP提供商确认tag名称,或改用分支名 |
repo init 报错 "fatal: Not a git repository" |
当前目录不是空目录,或已有.repo目录 |
换一个空目录,或先 rm -rf .repo 再重试 |
我的经验: 遇到网络问题,别死磕。先检查 git ls-remote 能不能访问到Manifest仓库。如果连不上,换源或挂代理。如果连得上但同步慢,用 repo sync -j1 单线程跑,虽然慢但稳定,不容易断。
还有一个容易被忽略的问题:磁盘空间。Yocto源码加上后续的编译缓存,轻松吃掉50GB以上。我建议至少预留100GB的空闲空间。用 df -h 先看一眼,别等到编译到一半报磁盘满才后悔。
好了,源码获取这块,核心就是记住三步:装Repo → 选Manifest → repo init + sync。分支切换尽量用重新init的方式,别偷懒。网络问题多准备几个镜像源做备用。把这些搞定了,后面的编译工作才能顺利开展。