3. 开发环境搭建

做全志Tina Linux开发,第一步就是拿到源码。这事儿听起来简单,但里面坑不少。我见过不少新手,甚至一些老手,在源码同步上栽跟头——要么下载到一半断了,要么分支切得乱七八糟,最后编译出来的东西莫名其妙。

今天咱们就把这块彻底捋清楚。

3.1 Repo工具:Android遗产,Tina标配

Tina Linux的源码仓库,用的是Google为Android设计的Repo工具。说白了,Repo就是一个Python脚本,它帮你管理一堆Git仓库。Tina的源码不是单个仓库,而是由上百个Git仓库组成的集合——内核一个、uboot一个、各个组件各一个。

你想想看,要是手动一个个去git clone,光敲命令就得半天。Repo就是干这个的。

核心概念:Repo通过一个manifest.xml文件,描述所有子仓库的位置、分支和版本。你只需要操作Repo,它自动帮你搞定底层的Git。

3.1.1 安装Repo

先装Repo。我个人习惯把它放在用户目录下的bin文件夹里:

mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=~/bin:$PATH

嗯,这里要注意:国内网络环境,有时候连Google的服务器不太稳。我建议你提前把repo脚本下载好,或者用国内镜像源。我曾经在项目赶进度时,就因为网络问题卡在repo init这一步,急得直跺脚。

小技巧:把repo脚本放到版本管理里,团队统一使用同一个版本,避免因repo版本差异导致行为不一致。

3.1.2 Repo init:初始化工作区

拿到Tina的manifest仓库地址后,执行:

repo init -u <manifest仓库URL> -b <分支名> --depth=1

参数说明:

参数 作用 我的建议
-u 指定manifest仓库地址 用公司内部GitLab地址,别用公共的
-b 指定分支或tag 明确到具体版本号,别用master
--depth=1 浅克隆,只拉最新提交 强烈建议加,省时间省空间

为什么加--depth=1?Tina完整历史可能有几千个提交,全拉下来几十个G。你只是要编译,要历史干嘛?我刚开始做的时候没加这个参数,结果磁盘空间直接爆了。

3.2 Git仓库管理:理解Tina的仓库结构

初始化完成后,你会看到.repo目录和一堆.git文件。别慌,这是Repo的魔法。

实际开发中,你主要操作的是这些子仓库:

  • lichee/:存放boot0、uboot、内核等底层代码
  • brandy/:一些基础库和工具链相关
  • package/:各个应用和组件的源码
  • target/:板级配置和镜像打包脚本

每个子仓库都是独立的Git仓库。你可以cd进去,执行git log、git status、git diff——跟普通Git仓库一模一样。

注意:不要在顶层目录执行git命令!顶层目录不是Git仓库,是Repo管理的。你需要在子仓库里操作Git。

3.3 分支切换与同步策略

这块是实战中的重头戏。Tina开发通常涉及多个分支:开发分支、稳定分支、客户定制分支。怎么切、怎么同步,有讲究。

3.3.1 查看当前分支状态

先看看所有子仓库分别在哪个分支上:

repo status

这个命令会列出所有有变动的仓库。如果想看所有仓库的分支信息:

repo info -o

3.3.2 切换分支

切换所有子仓库到同一个分支:

repo init -b <新分支名>
repo sync

注意顺序:先repo init改manifest的分支,再repo sync拉取。

但有时候你只想切换个别仓库。比如内核要切到某个fix分支,其他仓库不动:

cd lichee/linux-5.4
git checkout <fix分支名>

我个人习惯是:尽量用repo统一管理分支,只在特殊情况下手动切个别仓库。否则时间一长,你都不知道哪些仓库在哪个分支上,编译出来一堆奇怪的问题。

3.3.3 同步策略:避免冲突的秘诀

团队协作时,同步是家常便饭。但同步不当,冲突能让你改到怀疑人生。

我总结了一套同步流程:

  1. 先提交本地修改:有未提交的改动,先git commit或者git stash
  2. 执行repo sync:拉取远程最新代码
  3. 处理冲突:如果有冲突,手动解决
  4. 重新编译验证:确保同步后能编译通过

我的血泪教训:曾经有一次,我没提交本地修改就直接repo sync,结果本地改动被覆盖了。虽然Git有reflog能找回,但折腾了大半天。从那以后,我每次同步前必先git status检查一遍。

3.3.4 分支同步的高级技巧

有时候你需要把开发分支的改动合并到稳定分支。这时候别直接repo sync,要用repo upload或者手动cherry-pick。

我常用的做法:

# 在开发分支上
git format-patch <基准提交>..HEAD --output-directory=/tmp/patches

# 切到稳定分支
repo init -b stable-v1.0
repo sync

# 逐个应用补丁
cd <对应仓库>
git am /tmp/patches/*.patch

这样能精确控制哪些改动过去,哪些留下。比直接merge干净得多。

3.4 知识结构图:源码获取与同步全流程

下面这张图,把整个流程串起来了。你对照着看,心里就有谱了。

源码获取与同步全流程 1. 安装Repo 2. repo init 3. repo sync 4. 进入子仓库开发 5. git add/commit 6. repo upload 7. 切换分支 8. repo sync同步 9. 解决冲突 10. 编译验证 11. 提交测试 💡 核心原则:先提交本地修改 → 再同步远程代码 → 最后编译验证。顺序不能乱。 💡 分支切换用 repo init -b,个别仓库调整用 git checkout。

3.5 常见问题与避坑指南

最后,分享几个我踩过的坑,你遇到了直接照着处理就行。

问题 现象 解决办法
repo sync卡住不动 进度条停在某个仓库 Ctrl+C中断,执行repo sync --no-clone-bundle绕过bundle下载
分支混乱 不同仓库在不同分支 执行repo forall -c git checkout <目标分支>统一切换
磁盘空间不足 repo sync报错 加--depth=1重新init,或者清理.repo目录中的旧对象
冲突无法解决 git merge冲突 用git mergetool可视化解决,或者回退后重新cherry-pick

曾经有一次,我在客户现场做技术支持,需要紧急同步一个补丁。结果repo sync到一半网络断了,再执行就报错说.repo目录锁住了。后来发现是之前sync进程没完全退出,锁文件没释放。解决办法:rm -f .repo/.repo_lock,然后重新sync。这事儿让我养成了一个习惯——每次sync前先检查有没有残留的锁文件。

好了,源码获取与同步这块,核心就是这些。记住:Repo是壳,Git是核。理解了这个关系,你就能驾驭Tina的源码管理。动手试试吧,光看是学不会的。