2.3 Android系统代码和编译

2.3.1 获取Android源代码

获取Android完全的源代码方法包括初始化代码仓库和获取代码两个步骤,每个步骤可以增加不同的参数。

对于Android的代码仓库,初始化代码仓库的一般方法如下所示:

    $ repo init -u git://android.git.kernel.org/platform/manifest.git

在Linux控制台的命令行中,一般需要在一个新建的目录中执行repo init,其过程将显示一些信息,内容如下所示:

    $ repo init -u git://android.git.kernel.org/platform/manifest.git
    Getting repo ...
      from git://android.git.kernel.org/tools/repo.git
    remote: Counting objects: 1090, done.
    remote: Compressing objects: 100% (486/486), done.
    remote: Total 1090 (delta 684), reused 949 (delta 583)
    Receiving objects: 100% (1090/1090), 310.73 KiB | 37 KiB/s, done.
    Resolving deltas: 100% (684/684), done.
    From git://android.git.kernel.org/tools/repo
     * [new branch]      maint      -> origin/maint
     * [new branch]      master     -> origin/master
     * [new branch]      stable     -> origin/stable
     * [new tag]         v1.6.10.2  -> v1.6.10.2
    From git://android.git.kernel.org/tools/repo
     * [new tag]         v1.0       -> v1.0
    # ……得到众多tag,省略
     * [new tag]         v1.6.9.7   -> v1.6.9.7
     * [new tag]         v1.6.9.8   -> v1.6.9.8
    Getting manifest ...
      from git://android.git.kernel.org/platform/manifest.git
    remote: Counting objects: 473, done.
    remote: Compressing objects: 100% (214/214), done.
    remote: Total 473 (delta 171), reused 429 (delta 154)
    Receiving objects: 100% (473/473), 112.70 KiB | 9 KiB/s, done.
    Resolving deltas: 100% (171/171), done.

出现以上的内容,说明第一步获取已经完成。不需要用户的控制,过程将继续进行,在控制台中,继续显示的内容如下所示:

    From git://android.git.kernel.org/platform/manifest
     * [new branch]      android-1.5 -> origin/android-1.5
     * [new branch]      android-1.5r2 -> origin/android-1.5r2
     * [new branch]      android-1.5r3 -> origin/android-1.5r3
     * [new branch]      android-1.5r4 -> origin/android-1.5r4
    # ......省略中间的各个branch
     * [new branch]      android-2.1_r2.1p2 -> origin/android-2.1_r2.1p2
     * [new branch]      android-2.1_r2.1s -> origin/android-2.1_r2.1s
     * [new branch]      android-2.2_r1 -> origin/android-2.2_r1
     * [new branch]      android-2.2_r1.1 -> origin/android-2.2_r1.1
    # ......省略中间的各个branch
     * [new branch]      cdma-import -> origin/cdma-import
     * [new branch]      cupcake    -> origin/cupcake
     * [new branch]      cupcake-release -> origin/cupcake-release
     * [new branch]      donut      -> origin/donut
     * [new branch]      donut-plus-aosp -> origin/donut-plus-aosp
     * [new branch]      eclair     -> origin/eclair
     * [new branch]      froyo      -> origin/froyo
     * [new branch]      master     -> origin/master
     * [new branch]      release-1.0 -> origin/release-1.0
     * [new branch]      tools_r7   -> origin/tools_r7
    # ......省略中间的各个tag
     * [new tag]         android-2.2_r1 -> android-2.2_r1
     * [new tag]         android-2.2_r1.1 -> android-2.2_r1.1
     * [new tag]         android-cts-2.1_r2 -> android-cts-2.1_r2
     * [new tag]         android-cts-2.1_r3 -> android-cts-2.1_r3
    # ......省略中间的各个tag
     * [new tag]         android-sdk-tools_r3 -> android-sdk-tools_r3
     * [new tag]         android-sdk-tools_r4 -> android-sdk-tools_r4
     * [new tag]         android-sdk-tools_r5 -> android-sdk-tools_r5
    From git://android.git.kernel.org/platform/manifest
     * [new tag]         android-1.0 -> android-1.0
    Your Name  [Han Chao]:
    Your Email [hanchao3c@gmail.com]:

最后出现可以输入用户名和E-mail账户。在以上执行的流程中,出现的各个[new tag]和[new branch]的内容可以作为repo init中-b指定的参数。如果没有指定,将使用master分支的最新版本。

repo init之后,在执行的目录中,将生成隐藏目录.repo。这里面的内容是工程管理的信息。

    $ tree  -L 1 .repo/
    .repo/
    |-- manifest.xml -> manifests/default.xml
    |-- manifests
    |-- manifests.git
    |-- project.list
    |-- projects
    `-- repo

文件manifest.xml为repo工程的描述文件,是一个到.repo/manifests/default.xml文件的连接。这个文件表示repo时包含的各个工程,其片段如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <manifest>
      <remote  name="korg"
              fetch="git://android.git.kernel.org/"
              review="review.source.android.com" />
      <default revision="master"
              remote="korg" />
      <project path="build" name="platform/build">
        <copyfile src="core/root.mk" dest="Makefile" />
      </project>
      <project path="bionic" name="platform/bionic" />
      <project path="dalvik" name="platform/dalvik" />
      <project path="development" name="platform/development" />
      <project path="frameworks/base" name="platform/frameworks/base" />
    </manifest>

其中,path表示工程获取后的路径(基于当前目录),name表示工程的名称,也是该工程在服务器上的相对路径。

在repo init的时候,使用-b选项可指定初始化的版本的方法如下所示:

    $ repo init -u git://android.git.kernel.org/platform/manifest.git -b release-1.0
    $  repo  init  -u  git://android.git.kernel.org/platform/manifest.git  -b  android
-sdk-1.5_r1
    $ repo init -u git://android.git.kernel.org/platform/manifest.git -b android-2.2_r1

在经过repo init之后,可以使用repo获取Android的全部代码,方法如下所示:

    $ repo sync

repo sync是主要从服务器上取内容的过程,执行时间将比较长。可以通过repo sync-j5来并行加速。5是并行的线程数,可自行调整。

使用repo sync的时候,也可以同步一个单个工程的内容,需要使用工程的名称作为repo sync的参数,工程的名称可以从manifest.xml获得。

    $ repo sync {project_name}

例如,以下的命令表示同步dalvik虚拟机项目:

    $ repo sync platform/dalvik

如果前面已经有过了同步,目前只需要使用sync进行更新的话,使用工程的路径也是可以的。这样的方式更为方便。

例如,在源代码的根目录中,再次同步虚拟机项目(dalvik)的方法可以如下所示:

    $ repo sync dalvik

repo工具实际上是对git的封装。直接使用git clone的方式也可以获取一个工程的代码,方法如下所示:

    $ git clone git://android.git.kernel.org/ + project path

有些没有包含在repo工程中的代码,还只能使用git clone的方式获取。

repo同时也是一个方便管理众多git库组成的Android工程的好工具。repo start,repo branches,repo prune,repo forall等命令,能够极大地方便开发人员对众多git库的同时管理。