前言和repo简介
众所周知,当前世界上最大的同性交友网站GitHub,里面几乎收藏了全球所有的代码。那么安卓系统的源代码也都保存在Github上,但安卓系统具体包含的有上百个git代码库。因此想要安卓系统源代码,一个一个把所有组件的git库git clone
下来就可以了,但这种方式过于呆萌,不像一个程序猿。对于程序猿,这种重复性的工作自然通过脚本就可以轻松实现,优快云上也都有很多人提供了这种脚本。不过贴心的谷歌官方为了方便大家下载AOSP,也提供了一个脚本工具——repo
。
根据上面的描述,大家也都能猜到实际上repo
就是一个包含了一系列git
命令的脚本文件,官方和华为云上都有中英文文档详细介绍该工具的具体使用方法。其主要思路就是通过xml
格式的manifest文件来定义一个比较大的系统中包含的所有project
信息,之后repo
就根据这些定义以及当前本地文件的状态,去执行相应的git
命令。
源码下载
由于安卓是谷歌的项目,而国内由于墙的原因,按照谷歌官方文档往往无法正常下载,好多人可能谷歌的官方文档链接都打不开。翻墙的方式现在也有很多,不过没有VPN的同学也可以在国内很方便地使用清华AOSP源和中科大AOSP源,下载AOSP源码。
准备repo
首先repo实际上就是一个python脚本,因此python一定要安装好,并且配置好环境变量。从git库同步代码自然也少不了git命令,安装好git之后也需要配置好git中的用户名和邮箱,常用如下命令:
git config --global user.name "username"
git config --global user.email "your.email@xxx.com"
之后与AOSP类似,repo脚本也有三个来源:
- 谷歌官方脚本:
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
- 清华源:
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o ~/bin/repo
- 中科大源:
curl -sSL 'https://gerrit-googlesource.proxy.ustclug.org/git-repo/+/master/repo?format=TEXT' |base64 -d > ~/bin/repo
要运行repo
自然就要赋予该脚本文件运行权限:chmod a+x ~/bin/repo
,之后就可以使用该脚本进行源代码下载和同步了。
初始化
之前提到repo
命令需要读取xml
格式的manifest文件来了解整个系统中包含的各个项目的具体信息。因此先要运行repo init
方法下载AOSP的项目清单文件。其中用到的两个主要参数分别为:
-u
:即获取清单文件的URL,既然有三个源头,清单文件也有三个URL:- 谷歌源:https://android.googlesource.com/platform/manifest
- 清华源:https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest
- 中科大源:git://mirrors.ustc.edu.cn/aosp/platform/manifest
-b
:对应AOSP的版本或分支(branch),AOSP的安卓版本和对应的分支tag列表可在官网查询。
具体的初始化命令举例如下,从谷歌官方下载安卓11的一个修订版:
repo init -u https://android.googlesource.com/platform/manifest -b android-11.0.0_r33
repo的运行过程中会尝试访问官方的git源更新自己,因此若报错无法连接到 gerrit.googlesource.com
类的问题,可以通过设置环境变量REPO_URL
使其到清华源或中科大源去检查更新,具体的URL与下载repo的路径一致:
- 清华repo:
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
- 中科大repo:
export REPO_URL='https://gerrit-googlesource.proxy.ustclug.org/git-repo'
经过初始化后,就有了.repo
文件夹,其中.repo/manifests/default.xml
就是AOSP包含的所有git项目的列表信息。
代码同步
最后执行repo sync
也就是具体的下载更新的过程。该过程时长根据网速决定,下载下来的内容接近100G,因此硬盘一定要保证有充足的空间。
问题总结
网络错误
下载过程中,往往有各种GnuTLS的网络报错,具体报错信息如下:
curl 56 GnuTLS recv error (-9): Error decoding the received TLS packet
curl 56 GnuTLS recv error (-54): Error in the pull function.
GnuTLS recv error (-110): The TLS connection was non-properly terminated
网上搜索有多种解决方案:
- 对git进行如下的设置:
# 增加git缓存 git config --global http.postBuffer 5000000000 # 关闭git SSL验证 git config --global http.sslVerify false # 关闭git压缩 git config --global core.compression -1
- 设置网卡,增加网络的MTU值,到最大10000;
- 完整安装gnutls包:
sudo apt install gnutls-bin
; - 重新编译git,使用openssl库代替GNUTLS库,参考优快云博客;
- 设置为单线程下载,在同步时添加
-j1
参数,使同步过程仅使用一个线程repo sync -j1
;
上述方法均不成功,仍然会有网络问题爆出。尤其是单线程同步,设置为单线程导致同步十分缓慢,而且同样也会有错误爆出,强烈不推荐!
找不到版本
除了网络错误,下载过程中同样也有如下的版本错误:
platform/build/blueprint:
fatal: 无法找到远程引用 refs/tags/android-11.0.0_r33
error: Cannot checkout platform/build: ManifestInvalidRevisionError: revision refs/tags/android-11.0.0_r33 in platform/build not found
error: in `sync`: revision refs/tags/android-11.0.0_r33 in platform/build not found
然而在谷歌官网可以看到/platform/build
下存在android-11.0.0_r33
的tag,并且对应的网页也是可以打开的。
个人小结
个人认为就算是版本找不到的问题,貌似也是网络原因导致的,总而言之下载过程最好保证有一个较为良好的网络环境。同步过程中的问题可以忽视,但同步完成后,发现仅下载了50G左右,而且内容绝大多数都在隐藏文件夹.repo
中,故此时可以认为没有成功下载。最简单的方法实际上最终解决了问题,那就是不断尝试repo sync
。并且尝试的过程中,如果有VPN,也最起码使用VPN进行一次sync。同时没有必要在多个源上重新下载,每次同步都可以在几个AOSP源之间进行切换,切换的方式很简单,就是修改.repo/manifests.git/config
文件,替换其中的url
参数:
- 谷歌官方:
url = https://android.googlesource.com/platform/manifest
- 清华源:
url = https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest
- 中科大源:
url = git://mirrors.ustc.edu.cn/aosp/platform/manifest
同一个文件夹下每次repo sync
使用不同的源是没有问题的,本质上使用git
,其优势就在于可以检测到不同,并且仅同步不同之处。