说实话,“配置 repo 编译环境”这个标题看着不长,但凡是亲手配过 Android 系统源码、或者基于多仓管理的大型项目编译环境的人,都知道这里面水有多深。你可能会想,repo 不就是 Google 出的一个仓库管理工具,照着官方文档敲几行命令,把源码拉下来就能编了吗?实际上一路踩下来,你会发现它牵扯到系统环境、Python 版本、Git 配置、磁盘规划、网络镜像、并发参数、编译缓存,甚至是文件描述符上限这些非常琐碎但每一个都能让你卡半天的细节。
这篇文章就是我把自己配置 repo 编译环境的完整过程、踩坑记录和优化经验整理出来的实操向总结。我不会只贴几条命令就说“搞定”,而是会把每个关键步骤背后的原理和取舍讲透,让新手少走弯路,也让有一定基础的人能查漏补缺。我们直接从零开始,一直到源码同步完成、编译环境能跑起来为止。
1. 动手前的整体设计:理解 repo 到底是什么
1.1 没有 repo 的世界:多 Git 仓库的灾难现场
先想一个问题:为什么需要 repo?如果你只参与过一个仓库的小项目,Git 本身完全够用。但像 Android 系统这种级别,源码拆成了少则几百个、多则上千个独立的 Git 仓库。每个仓库都有自己的提交历史、自己的分支,而系统整体要求某一次构建必须使用所有仓库的特定提交组合,否则编出来的东西根本对不上。
如果没有 repo,你要做的是:人工把所有仓库地址收进一个清单,写脚本逐个 clone,再锁定 commit hash,更新的时候再逐个 fetch 和 checkout。听起来好像可行,但实际操作上非常痛苦。仓库之间还有路径依赖,A 仓库必须放在 vendor/x 目录、B 仓库必须放在 packages/apps/y 目录,手动摆放容易出错,而且没有任何“版本一致性”的保证。更别提多人协作时,每个人本地仓库的状态都可能不一样,排查问题会变成灾难。
这就是 repo 存在的根本原因——它是为了管理“一组 Git 仓库”的元工具,解决的不是单个仓库的版本控制,而是“上千个仓库如何保持协调一致”的问题。
1.2 repo 的定位:一个管家的视角
我习惯这样理解 repo:Git 是每个工人手里那套工具箱,负责具体干活;repo 是管家,拿着一个总账本(manifest 清单),告诉每个工人你站在哪、该干什么活、当前时期应该用哪个版本。
这个总账本就是一个 XML 格式的 manifest 文件。它定义了仓库名、路径、所属分组、默认分支、以及每个仓库锁定的提交版本。repo init做的事情,就是把这个 manifest 仓库拉下来,建立一套管理数据库;repo sync做的事情,则是严格按照 manifest 清单去并行地拉取、更新所有仓库到指定状态。repo start、repo upload这些则是辅助你基于该清单创建分支、向代码审核服务器提交改动。
理解这层关系非常重要,因为你后面遇到任何同步异常,最终都要回到“manifest 怎么写的、我的环境哪里跟它冲突了”这个根本上来排查。配置 repo 编译环境,本质上不是“装一个软件”,而是“把一个多仓库项目的版本管理编排逻辑,从服务器完整复刻到本地”。
1.3 三种“编译环境”要分清:工具链、依赖、顶层构建
还有一个很容易混淆的地方:当我们说“配置编译环境”时,其实包含三个不同层面。第一是工具链环境:编译要用的 GCC、Clang、JDK、Python、Make、Ninja 等,也就是系统级工具。第二是项目依赖环境:比如 Android 编译需要特定版本的 OpenJDK、需要某些系统库,以及 repo 同步出来的源码树。第三是顶层构建系统:在源码树根目录执行source build/envsetup.sh、lunch、make这一套流程,背后是 Soong/Ninja 这样的构建框架。
很多人配置失败,就是因为把这三个层面混为一谈了。可能系统里已经有某个工具的版本,但它和项目要求的版本不一致;也可能源码同步到一半就以为环境好了,结果 lunch 阶段才暴露问题。我会在后面的章节里分别覆盖这三个层面的准备与校验,确保不是“只把 repo 装好,剩下随缘”。
2. 环境准备:把基础工具一次装齐
2.1 操作系统与磁盘规划
先讲系统选择。虽然 docs 上写了 macOS 和 Linux 都行,但我个人的强烈建议是:主用 Ubuntu 20.04 LTS 或 22.04 LTS,虚拟机和 WSL 不是不能用,但坑比较多,最好直接物理机或者专业的 Linux 工作站。
为什么选 LTS?因为 Android 这类大型项目的编译依赖 name 了很多特定的系统库和工具链版本,新发布的非 LTS 版本往往会升级库或调整默认配置,导致某个依赖行为变化。LTS 版本有长达五年的维护期,网上搜索踩坑贴时覆盖度也最高,遇到问题能搜到对应解法。如果你用 Arch 或者其他滚动发行版,不是不行,但你要有足够的心理准备去手动解决依赖漂移问题。
磁盘规划这块我多说几句,因为很多人真的在这里翻车。Android 13 的源码树在完整同步并开启 git 仓库后,占用大约 100GB 到 120GB,但编译产物是另一回事。make时会生成 out 目录,一次完整构建可能需要额外 80GB 以上。再加上你以后可能要编多个不同分支的产品,或者保留多个 manifest 工作目录,空间会迅速膨胀。我的建议是:
- 系统盘和数据盘分开,源码放置在独立的数据盘上,避免重装系统时血本无归。
- 预留 400GB 到 500GB 可用空间。虽然 200GB 也能完成一次构建,但你会活得非常紧张。
- 文件系统推荐 ext4,不要用 F2FS 或某些压缩文件系统,部分在 I/O 密集场景下会带来奇怪问题。
如果你像我一样只能装在一台机器上,至少确认磁盘剩余空间超过 250GB 再开始,否则 sync 到一半磁盘满,你会崩溃的。
2.2 必备工具链安装
在 Ubuntu 上,第一步就是先把基础包装齐。官方推荐一次安装很多包,但我会按自己的实际操作拆开讲,让你明白每一个到底是干嘛用的。
sudo apt update sudo apt upgrade -y sudo apt install -y git-core gnupg flex bison build-essential zip curl zlib1g-dev sudo apt install -y libc6-dev-i386 libncurses-dev x11proto-core-dev libx11-dev sudo apt install -y lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig这一堆包看着多,其实都是为了应对编译过程中的具体需求。比如libc6-dev-i386是 32 位兼容库,Android 编译中某些 host 工具还要以 32 位模式运行;libncurses-dev和libxml2-utils分别服务于终端交互和 XML 解析;flex和bison是词法、语法分析器,构建某些工具时需要通过它们生成代码。我更推荐的做法是装完后跑一遍sudo apt install -y openjdk-11-jdk(针对 Android 12/13 及之前版本),并确认python3 --version不低于 3.6,repo 的新版本对 Python 3 的依赖已经非常明确,还在用 Python 2 的教程可以忽略了。
这里有个容易忽略的细节:Git 版本不要太老。Ubuntu 20.04 自带 Git 2.25,够用,但如果你在同步某些超大仓库时遇到协议或索引格式问题,可以考虑通过向后源安装新版 Git。例如:
sudo add-apt-repository ppa:git-core/ppa sudo apt update sudo apt install -y git新版 Git 对管理工作目录下的浅克隆、部分克隆(partial clone)、以及引用完整性处理都有改进,同步大项目时能明显降低“对象校验失败”这类概率。
2.3 全局 Git 配置与文件描述符调整
很多刚接触 repo 的人会漏掉 Git 全局配置,但这一步其实决定你后续repo start、repo upload是否能正常工作。
git config --global user.name "Your Name" git config --global user.email "your_email@example.com" git config --global color.ui true git config --global core.filemode falsecore.filemode false在 NTFS 挂载目录和某些文件系统上尤其重要,否则 Git 会把“文件权限位变化”当成大量未提交的修改,review 时惨不忍睹。如果你的源码目录位于某个共享目录或者挂载盘上,这一行真的能救你。
接下来是文件描述符限制。repo sync 会开启大量并发进程,每个进程都要占用文件描述符。Ubuntu 默认的ulimit -n只有 1024,跑高并发同步时很容易出现 “Too many open files” 的报错。我一开始就踩了这个坑,sync 到一半突然失败,排查了很久。
ulimit -n 65536但这只是临时生效,推荐直接写入~/.bashrc:
echo "ulimit -n 65536" >> ~/.bashrc source ~/.bashrc这一行看似不起眼,但它是保证高并发同步稳定性的关键之一。不要等到排错阶段才想起来它。
3. 安装 repo 并完成初始化
3.1 获取 repo 脚本的两种方式与校验
repo 本身只是一个 Python 脚本,功能是把对多仓库的操作转换成一系列 Git 命令。所以安装 repo 其实没有复杂的编译过程,核心就是“把脚本放到 PATH 里,并赋予可执行权限”。
标准方式:
mkdir -p ~/bin curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo chmod a+x ~/bin/repo但国内访问这个官方地址经常超时,所以实际操作中我通常使用镜像源,比如清华的 git-repo 镜像:
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo chmod a+x ~/bin/repo然后把~/bin加入 PATH:
echo 'export PATH=$PATH:~/bin' >> ~/.bashrc source ~/.bashrc校验是否安装成功:
repo --version如果能看到类似repo launcher version 2.x的输出,说明脚本已经可用。这里我强烈建议你不要跳过校验步骤,因为网上有大量教程给的下载地址已经失效,返回的是 HTML 错误页,直接执行会收到一个诡异的SyntaxError,白白浪费时间。下载完成后用file ~/bin/repo看一眼,确认是 Python 脚本或 ASCII 文本,而不是 HTML 文档。
3.2 repo init 参数详解:manifest 仓库、分支、local mirror
repo init是后续一切的地基。这条命令的核心是告诉工具:你要跟随哪个 manifest 仓库、使用哪个分支。以 Android 13 为例:
mkdir -p ~/aosp cd ~/aosp repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-13.0.0_r1这里的-u指定 manifest 仓库,-b指定分支。如果省略-b,repo 会使用 manifest 仓库的默认分支,通常是 master,我不太建议这么做。因为 master 分支每天都在变,今天能同步成功,明天可能就会因为某个仓库临时提交了坏改动而编译失败。锁定一个明确、可重复的环境永远是对的。
如果你自己 fork 了一份 manifest,或者想使用内部团队维护的清单,那么-u换成自己仓库地址即可。另外两个参数我也常用:
repo init -u <manifest_url> -b <branch> --partial-clone--partial-clone是 Git 的部分克隆特性,它允许仓库在 fetch 时只下载必要的对象,而把大数据量的 blob 留在服务器端按需拉取。对网络带宽不足或磁盘有限的场景来说,这个参数能大幅缩短同步时间。但它也有代价:后续 checkout 或者构建时需要访问服务器补充对象,如果网络不稳定,反而会拖慢构建。我个人在带宽条件一般时宁可不加,全量同步虽然慢,但一次到位,构建阶段不会突然卡在“远程获取对象”上。
另外,repo init会在当前目录下生成.repo目录,所有 manifest、项目对象、管理脚本都存在这里面。所以创建专用目录是必要的,不要直接在~目录下 init,否则.repo散落在多个主目录里,后续维护会很乱。
执行完repo init后,建议用repo info查看一下解析后的 manifest 是否生效,确认当前分支、manifest 仓库地址是否符合预期。
3.3 解决首次初始化的常见报错
我第一次配置时,卡在repo init就在这里耗了很久。下面是最常见的三个问题。
第一个是 HTTPS 证书校验失败。如果你在办公网络或某些代理环境下,curl 或 Git 访问镜像源时可能报证书错误。此时不要直接关闭 SSL 校验,而是先检查系统证书是否完整:
sudo apt install ca-certificates -y sudo update-ca-certificates如果仍然失败,可以临时在仓库级配置中为指定域名关闭校验,但不推荐永久关闭,因为源码下载和后续上传都走 HTTPS,证书校验被整体关掉是会埋雷的。
第二个是repo: command not found。这通常不是 repo 本身的问题,而是~/bin没有加入 PATH,或者当前 shell 还没重新加载.bashrc。执行source ~/.bashrc即可,避免新开终端忘了这一步时产生误解。
第三个是在 init 阶段出现fatal: manifest 'default.xml' not found。这常常是因为 manifest 仓库地址本身就不是一个标准 AOSP manifest,或者分支名拼写有误。但还有一个容易被忽略的原因——某些第三方项目把 manifest 文件放在仓库的子目录里,这时候需要配合-m参数指定具体文件:
repo init -u <manifest_url> -m custom-manifest.xml当你发现-b分支没问题但 manifest 找不到时,先检查仓库根目录有哪些.xml文件,再决定是否需要-m。
4. repo sync 同步源码:从零拉到可编译状态
4.1 同步策略选择:全量、增量、断点续传
repo sync是整个过程中耗时长、最容易出问题的环节。我建议不要指望一条命令跑完就不管,而应该根据网络环境选择合适的策略。
全量同步:
repo sync -j8 -c-j8是并发任务数,-c表示只同步当前分支的代码。加上-c会显著减少要拉取的对象数量,对不需要全部分支历史的人来说非常划算。如果你只是要编译当前分支的某个版本,而不做深入的 Git 历史分析,建议始终带上-c。
增量同步则是在已经有部分代码的基础上,只拉取新的提交和对象。repo 本身会判断哪些仓库需要更新,所以重复执行同样的repo sync就是增量同步。实际体验中,增量同步的速度会比全量快很多,但有一个前提:不要中断上一次 sync 后手动修改仓库状态,否则对象库不一致,增量同步会反复校验甚至报错。
断点续传是我用得最多的技巧。如果同步中途因为网络或磁盘原因失败,repo sync 本身是可以继续执行的,因为每个仓库都已 clone 的本地 Git 对象会被保留,再次执行只会补充未完成的部分。但对于网络极不稳定的环境,我更推荐一种“循环重试”的思路:
repo sync -j4 -c while [ $? -ne 0 ]; do echo "sync failed, retrying..." sleep 5 repo sync -j4 -c done这样可以自动在失败后重试,直到所有仓库都同步完成。这个脚本我用的频率很高,比一遍遍手动执行要靠谱得多。当然,如果你能使用内网镜像或公司自建的 Git 镜像,上面的多数问题都不存在,这部分主要是给网络条件普通的朋友参考。
4.2 并行参数与资源控制
-j参数的设置看起来简单,但很有讲究。它决定的是 repo 同时拉取、更新多少个仓库。设置太高,瞬间建立大量 SSH/HTTPS 连接,容易触发服务端限流,并且本机文件描述符和内存都会吃紧;设置太低,几百上千个仓库一个个拉,时间周期拉满。
我个人的经验公式是:并发数控制在 CPU 核心数的 1.5 到 2 倍之间,但上限 16。机器是 8 核 16 线程,-j12到-j16都合适;如果是 4 核的老机器,-j6就好。注意这里的资源消耗主要在内存和网络,而不是 CPU 算力,所以不要因为 CPU 强劲就盲目拉到 32。
另外我还有个小习惯:把.repo目录内的大文件抓取与解压操作放到内存盘或者高速 SSD 上。因为 repo sync 的核心操作是 Git 对象解压,这部分 I/O 量极大,机械硬盘在这里表现非常糟糕。如果源码放在普通 HHD 上面,哪怕网络速度再快,同步实际耗时也会被磁盘写入速度拖垮。一个可行的优化是使用 SSD,并把 Git 的 delta 压缩级别调低一些:
git config --global core.compression 0这会让 Git 在传对象时不做额外的压缩,提高同步速度,代价是网络传输量稍微上升。对于内网镜像环境,这种方式通常更快。
4.3 同步完成后的自检清单
当 repo sync 跑完,没有报错并停在提示符时,先别急着开始编译。我会按下面这个清单做一次自检,避免后面白跑一轮。
repo status这个命令会概述每个仓库当前的工作区状态,如果显示clean,说明源码树状态没问题。接着确认关键仓库是否存在且路径正确,比如:
ls build/make/ ls frameworks/base/ ls packages/apps/Settings/如果这些目录存在,说明同步基本没出差错。然后检查磁盘剩余:
df -h .确认可用空间充足,给编译产物留下余地。最后可以看一下.repo/manifest.xml的内容,确认当前锁定的 revision 和预期分支一致。
还有一个容易被忽视的点:源码树所有权与当前用户是否一致。如果你用 sudo 执行过 repo 相关命令,某些仓库的 Git 对象文件可能会被改成 root 所有,后续普通用户执行repo sync或编译时会遇到权限错误。遇到这种问题,最简单的修复方式就是:
sudo chown -R $(whoami) .这条命令会把整个源码树的所有权修改为当前用户,虽然不是最优解,但能省很多事。建议从一开始就避免用 sudo 跑 repo 命令。
5. 编译环境验证与构建配置
5.1 加载编译环境脚本:envsetup.sh 到底做了什么
源码同步完成后,进入根目录执行:
source build/envsetup.sh很多新手以为这就是“设置编译环境”,执行完就万事大吉。实际上这个脚本做的是注册一系列辅助函数,比如lunch、mka、mmm、mm等。它并没有去检查 JDK 版本,也没有检测系统库,所以即使执行成功,也不代表环境完全可用。
lunch才是真正开始“组装”编译环境的关键一环。运行lunch时,如果不带参数,会弹出一个产品列表,让你选择是要编 AOSP 的某个模拟器 target,还是某个手机型号的 userdebug 版本。最常见的组合是:
lunch aosp_arm64-engaosp_arm64:针对 64 位 ARM 模拟器或设备的基础用户态镜像。aosp_x86_64:基于 x86_64 架构的模拟器镜像,编译速度快一些。eng:工程版,包含调试工具和额外权限,适合开发调试。userdebug:功能上接近 user 版本,但保留 root 权限,适合做系统调试。
选择哪一个取决于目标。如果是模拟器测试,sdk_phone_x86_64是常见的生产配置;如果是真机调试,就选对应的设备型号。每次切换产品配置后,构建系统的环境变量都会发生变化,所以切换目标后最好重新执行一次 lunch。
lunch执行时会读取build/target/product下目标产品的AndroidProducts.mk,检查目标依赖的架构、模块配置。如果这一步报错,往往不是环境问题,而是你选的 target 在当前分支中不存在,或者依赖的某个模块没有同步完整。
5.2 选择产品配置与修改构建配置
我建议不要直接跑make,第一次先跑一个轻量验证,比如编译某个关键模块,确认工具链和依赖都正常:
m -j$(nproc) libart这样可以快速看到编译流程是否能走到产物生成。如果这个模块能过,说明 host 工具链、交叉编译器、构建系统都基本就绪。再执行:
make -j$(nproc)完整编译 Android 系统的耗时取决于机器性能。以一台 16 核 32GB 内存、NVMe SSD 的机器为例,编 Android 13 首次全量构建通常在 30 到 60 分钟;如果磁盘和内存不给力,可能要三四个小时甚至更久。注意$(nproc)返回的逻辑核心数,但在内存不足时,编译会触发 OOM。我的经验是,16GB 内存最多用-j8,32GB 内存可以用-j16,如果内存更大再继续提升并发。构建系统有时候看起来 CPU 很闲,那是内存吃紧导致大量换页,白白浪费时间。
另外,如果你只修改了某个子系统,没必要全量 make。使用m、mm、mmm可以局部编译当前目录或指定路径下的模块。m在源码树任意子目录都能调用,它会在所有 Android.mk 或 bp 文件中搜索匹配的模块名;mm是编译当前目录所在模块;mmm是编译你指定的一个路径范围。这套机制配合 repo 的多仓结构特别好用,改完frameworks/base下的代码不用重新构建整个系统。
5.3 用 CCache 和配置缓存加速后续编译
开发过程中做增量编译是最常见的操作,但 C++ 和 Rust 代码的编译时间很长,每次都从零开始非常亏。CCache 就是用来缓存编译中间产物的工具。Android 官方也支持这个功能。
sudo apt install ccache -y export USE_CCACHE=1 export CCACHE_EXEC=$(which ccache)持久化配置可以写进~/.bashrc:
echo 'export USE_CCACHE=1' >> ~/.bashrc echo 'export CCACHE_EXEC=/usr/bin/ccache' >> ~/.bashrc设置缓存上限:
ccache -M 50G-M 50G表示最多缓存 50GB 的编译中间产物,针对 Android 这种大型工程,50GB 是比较合理的起点。如果机器空间富裕,可以涨到 100GB,效果更好。首次全量构建时 CCache 不会有太大帮助,因为它没有命中缓存;但从第二次开始,改动后重新编译的速度会明显提升。对我这种经常在 framework 层来回改代码的人来说,CCache 是“用了就回不去”的配置。
除了 CCache,Android 构建系统还支持buildid和soong的持久化缓存。在~/.ccache之外,Soong 在out/soong下有自己的构建缓存,默认不清理。如果后续修改了大量全局变量,这些缓存反而会带来误判问题,必要时可以清掉:
rm -rf out然后重新构建。首次会慢,但至少不会出现“改了代码但编出来的还是旧产物”的诡异情况。
6. 高频问题速查与避坑实录
6.1 初始化与同步阶段报错对照
| 报错信息 | 原因 | 排查与解决方案 |
|---|---|---|
repo: command not found | PATH 里没有~/bin | 检查~/.bashrc,重新 source;确认脚本可执行权限 |
fatal: Cannot get https://... | 网络不通或代理未配置 | 配置代理、更换国内镜像源,检查 DNS 和证书 |
fatal: manifest 'default.xml' not found | manifest 分支或路径不对 | 确认仓库地址和分支;用-m指定具体 manifest 文件 |
error: Cannot fetch <project> | 某个仓库地址不可达或已失效 | 逐个用git ls-remote判断;确认没有误改.repo/manifests |
Too many open files | 文件描述符上限不够 | 临时执行ulimit -n 65536,或写入~/.bashrc持久化 |
unable to access '...': SSL certificate problem | CA 证书过期或代理干扰 | 更新 ca-certificates;禁止整体关闭 SSL,尽量按域名配置例外 |
Failed to connect to ... port 443: Connection refused | 端口被封锁或服务不可达 | 检查 443 端口连通性;确保使用镜像域名而非被屏蔽的地址 |
这几个问题是我和周围同事踩得最多的。其中“连接被拒绝”和“证书问题”在镜像场景下出现的概率最高,优先确认你使用的镜像域名是否支持 HTTPS 且证书链完整。如果公司有内部代理,还需要给 Git 配置代理地址。
6.2 编译阶段常见报错与排查思路
编译阶段的报错比同步阶段复杂,但很多都可以通过“环境变量检查 + 组件依赖检查”来定位。
| 报错信息 | 原因 | 排查与解决方案 |
|---|---|---|
Unable to locate a Java Development Kit | JDK 版本不对或未安装 | Android 12/13 需要 OpenJDK 11,卸载其他版本,重新安装并配置JAVA_HOME |
No rule to make target ... | 源码树部分模块未同步完整 | 重新repo sync -c;确认同步没有中途失败 |
No such file or directory: prebuilts/... | prebuilt 仓库未同步或路径被移动 | 检查.repo/manifest.xml中对应路径,重新repo sync prebuilts/... |
out: Permission denied | out 目录所有权不对 | sudo chown -R $(whoami) .后再编译 |
virtual memory exhausted | 内存不足导致编译器崩溃 | 降低-j并发数;增加 swap;不要用-j超过内存能承受的上限 |
error: unsupported reloc | 系统库版本或架构不匹配 | 确认操作系统是 64 位;确认使用的 toolchain 与目标架构匹配 |
有一个隐蔽问题在正式编译前才会暴露:源码同步后out/host下的工具没有编译权限,或者缺少make、ninja等基础命令。因为 Android 构建系统会从源码树里的 prebuilt 拉取工具,系统级工具缺一两样不影响 init 阶段,但影响make阶段。所以如果在make早期就报 “command not found”,优先检查build-tools和prebuilts两个目录是否完整。
6.3 关于“repo 汉化”和第三方项目整合的两个常见误区
顺着热点词“repo 汉化补丁”多说一句:repo 工具本身是纯命令行英文界面,有人做了汉化补丁,把帮助信息和错误提示改成中文。这种补丁在资料查阅少的新手手里可能觉得亲切,但我个人不推荐在生产环境使用。repo 是一个直接操作 Git 对象和多仓状态的工具,错误信息里的英文关键词往往是网上搜索解决方案的唯一线索,一旦被汉化,你可能连“fatal: cannot fetch”这样的报错都不知道该怎么办,中文翻译一模糊,排查方向都会走偏。而且汉化补丁大多基于某个版本开发,repo 升级后容易出现兼容问题,突然报错反而增加风险。
第二个误区是很多人一看到“switch 编译环境搭建”这样的关键词,就以为 repo 和某个特定硬件平台绑定。其实不是,repo 只是多仓代码管理工具,它跟 Switch、手机、模拟器并没有直接绑定关系。你在配置任何需要“多仓协作编译”的项目时,步骤都是类似的:确认环境、init、sync、加载构建脚本。区别只在于 manifest 仓库地址和具体产品的构建命令不同。这个认知能帮你在换项目时快速迁移经验,不至于被各类不同平台的教程绕晕。我用 repo 管理过的项目至少有十来个,除了 Android 还有嵌入式 Linux、车载系统相关,基本思路完全一致,只是 manifest 里的仓库布局不同罢了。
7. 最后分享两个实用体会
配置 repo 编译环境这件事,回头看来最难的地方并不是哪一条命令特别深奥,而是整个流程里几十个细节环环相扣。任何一个环节出问题,后面跟着的是一连串奇怪报错。所以我个人的实操体会是:每次配置都写成清单,一个环境一个环境地核对,不要跳步。尤其在切换 Android 版本或者换新机器时,原来的配置不能照抄,必须重新确认 JDK 版本、磁盘空间、并发参数,因为不同分支对这些的要求差异可以很大。
再分享一个小技巧:如果条件允许,尽量在本地维护一个迷你镜像目录,把 manifest 仓库和你最常用的几个依赖仓库单独缓存起来。这样以后repo init和repo sync时只需要从本地拷贝,速度飞快,还能降低远程服务器故障带来的不确定性。这也解释了为什么有人会觉得某些项目同步特别快——不一定是网速好,而是他有一套成熟的缓存机制。配置 repo 编译环境的能力,说到底就是你对这套多仓管理机制的掌控程度,把这个练熟了,换什么项目都不慌。