25.2 安装repo

首先下载repo的引导脚本,可以使用wget、curl甚至浏览器从http://android.git.kernel.org/repo上下载。把repo脚本设置为可执行,并复制到可执行的路径中。在Linux上可以用下面的指令将repo下载并复制到用户主目录的bin目录下。


$curl-L-k http://android.git.kernel.org/repo>~/bin/repo

$chmod a+x~/bin/repo


为什么说下载的repo只是一个引导脚本(bootstrap)而不是直接称为repo呢?因为repo的大部分功能代码不在其中,下载的只是一个帮助完成整个repo程序继续下载和加载的工具。如果您是一个程序员,对repo的执行比较好奇,可以一起来分析一下repo引导脚本。否则可以直接跳到下一节。

看看repo引导脚本的前几行(为方便描述,把注释和版权信息过滤掉了),会发现一个神奇的魔法:


1 #!/bin/sh

2

3 REPO_URL='git://android.git.kernel.org/tools/repo.git'

4 REPO_REV='stable'

5

6 magic='—calling-python-from-/bin/sh—'

7 "" "exec" python-E "$0" "$@" "" "#$magic"

8 ifname=='main':

9 import sys

10 if sys.argv[-1]=='#%s'%magic:

11 del sys.argv[-1]

12 del magic


repo引导脚本是用什么语言开发的?这是一个问题。

第1行,有经验的Linux开发者会知道此脚本是用Shell脚本语言开发的。

第7行,是这个魔法的最神奇之处。既是一条合法的shell语句,又是一条合法的python语句。

第7行如果作为shell语句,执行exec,用python调用本脚本,并替换本进程。三引号在这里相当于一个空字串和一个单独的引号。

第7行如果作为python语句,三引号定义的是一个字符串,字符串后面是一个注释。实际上第1行到第7行,既是合法的shell语句又是合法的python语句。从第8行开始后面都是python脚本了。

repo引导脚本无论是用shell执行,还是用python执行,效果都相当于使用python执行此脚本。

repo脚本的真正位置在哪里?可以通过分析引导脚本repo得到。在引导脚本repo的main函数中,首先调用_FindRepo函数,从当前目录开始依次向上递归查找.repo/repo/main.py文件。


def main(orig_args):

main,dir=_FindRepo()


函数_FindRepo返回找到的.repo/repo/main.py脚本文件,以及包含repo/main.py的.repo目录。如果找到了.repo/repo/main.py脚本,则把程序的控制权交给.repo/repo/main.py脚本(省略了在repo开发库中执行情况的判断)。

在下载repo引导脚本后,没有初始化之前,当然不会存在.repo/repo/main.py脚本,这时必须进行初始化操作。