前言
好久没有双休一个周末了,唉,闲话不多说了,不管任何时候都要多学习充实自己。ROM Porting的工作是很繁琐的,涉及的知识点很多,这里介绍一下ROM Porting经常听到的名词和Repo工具的使用。
AOSP、AOKP、CM
相信很多Android发烧友对这几个单词都是耳熟能详了,这里还是给新入门的朋友们普及一下这几个单词背后的含义。
AOSP是“Android Open-Source Project”的缩写,中文名称为Android开放源代码项目。大家都知道Android是开源操作系统,所以Google每发布一个Android版本,都会给开源社区发放对应版本的源代码,也就是我们所说的AOSP ROM,这可以称得上是最为纯净的Android系统。可以用类比来让大家更清楚一些,例如国内多数盗版的Windows系统,几乎都是基于微软的MSDN制作,AOSP ROM即等相当于微软MSDN母盘的角色。
AOKP是“Android Open-Source Kang Project”,比AOSP多了一个“Kang”。在Android社区中,Kang表示这是一个被别人定制过的ROM,是一个来自民间的ROM。
CM是CyanogenMod的简称,Cyanogen团队是全球最大的第三方ROM编译团队,覆盖机型范围特别广,国内知名的ROM例如MIUI、锤子ROM都是基于CM实现的。严格意义上来说,CM ROM属于AOKP的范畴。CM ROM虽然一直遵从原生Android,但只有Google官方的才算真正的AOSP。
为什么使用Repo
上文介绍的AOSP是由许许多多有Git管理的项目组成的,例如,在Android4.2中,就包含了329个项目,每一个项目都是一个独立的Git仓库。这意味着,如果我们要创建一个AOSP分支来做新的feature开发,那么就需要到每一个子项目去创建对应的分支。这显然不能手动地到每一个子项目里面去创建分支,必须要采用一种自动化的方式来处理。这些自动化处理工作就是由Repo工具来完成的。当然,Repo工具所负责的自动化工作不只是创建分支那么简单,查看分支状态、提交代码、更新代码等基础的Git操作都可以用Repo来替代完成。
Reopo
Repo工具是由一系列的Python脚本组成的,这些Python脚本通过调用Git命令来完成自己的功能。比较有意思的是,组成Repo工具的那些Python脚本本身也是一个Git仓库,这个Git仓库在AOSP里面就称为Repo仓库,我们每次执行Repo命令的时候,Repo仓库都会对自己进行一次更新。
上面我们讨论的是Repo仓库,但是实际上我们执行Repo命令想操作的是AOSP。这就要求Repo命令要知道AOSP都包含有哪些子项目,并且要知道这些子项目的名称、仓库地址是什么。换句话说,就是Repo命令要知道AOSP所有子项目的Git仓库元信息。因为AOSP也是不断地进行迭代的,每一个版本所包含的子项目可能都是不一样的。这意味着需要通过另外一个Git仓库来管理AOSP所有的子项目的Git仓库元信息。这个Git仓库在AOSP里面就称为Manifest仓库。
到目前为止,我们提到了三种类型的Git仓库,分别是Repo仓库,Manifest仓库和AOSP子项目仓库。Repo仓库通过Manifest仓库可以获得所有AOSP子项目仓库的元信息。有了这些元信息之后,我们就可以通过Repo仓库里面的Python脚本来操作AOSP的子项目。那么,Repo仓库和Manifest仓库又是怎么来的呢?答案是通过一个独立的Repo脚本来获取,这个Repo脚本位于AOSP的一个官方网站上,我们可以通过HTTP协议来下载。
现在,我们就通过一个图来勾勒一下整个AOSP的Picture,它由Repo脚本、Repo仓库、Manifest仓库和AOSP子项目仓库组成,如图1所示:
Repo脚本
我们可以直接通过curl命令,通过http协议,获取最新的Repo脚本:
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo $ chmod a+x ~/bin/repo
Repo命令
repo init -u <url> [OPTIONS]
在当前目录下初始化repo,会在当前目录下生成一个.repo目录,就像Git Project目录的.git一样。
-u:指定一个URL,从这个URL中取得repository的manifest文件。获取的manifest文件放在.repo目录中,命名为manifest.xml,这个文件的内容其实就是所有被git管理的仓库列表。
[OPTIONS] -m:选择获取repository中的某一个特定的manifest文件,如果不具体指定,那么表示为默认的manifest文件(default.xml)。
[OPTIONS] -b:指定某个manifest分支。如果不指定-b参数,那么默认会使用master分支。
repo sync [project-list]
同步代码,下载最新的本地工作文件,更新成功,则本地文件和repository中的代码是一致的。可以指定需要更新的project,如果不指定任何参数,会同步Manifest文件中的所有git项目。
如果是第一次运行repo sync,则这个命令相当于git clone,会把repository中的所有内容都拷贝到本地。如果不是第一次运行repo sync,则相当于运行git remote update && git rebase original/branch
repo update [project-list]
上传修改的代码,如果你本地的代码有所修改,那么运行repo sync的时候,会提示你上传修改的代码,所有修改的代码分支会上传到Gerrit(基于web的代码review系统)。Gerrit接收上传的代码,会转换为一个个变更,从而可以让其它人来对比并且review修改提交的代码。
repo diff [project-list]
显示当前Project修改的代码和当前工作代码之间的差异。
repo start new_branch_name [specified-project]
在指定的Project上创建一个新的分支。
repo branch
查看所有分支
repo abandon <branch>
删除指定分支,无论是否merged。
repo forall [project-list] -c COMMAND
对指定的Project列表或者所有Project执行COMMAND命令。
repo status
显示Repo仓库中每个Project的状态。
repo download target revision
下载特定的修改版本到本地。
我的理解
由于AOSP项目由很多Git仓库构成,如果一个一个的git clone太过于浪费时间,因此需要使用Repo工具将Git仓库集合一口气下载到本地来。一旦Project下载到本地后,针对单个Project,均可以直接用Git命令去操作。因为我对Git命令更熟悉一些,所以我根本不需要去死记硬背Repo除了Repo init外的其他命令,直接使用对应的Git命令即可。