Android 系统源码分析——MacOs下的源码下载及编译

https://rainmonth.github.io/posts/A191012.html

[toc]

摘要

最近在研究Android系统的启动过程,就想着应该有一套自己的Android源码,边把之前一直想做的编译Android源码这件事提上了日程,过程比较曲折,但好歹最终编译成功了,仅以此文记录之。

环境说明

  • 要编译的目标Android版本:Android-8.1.0_r1
  • 操作系统版本:MacOS 10.14.6,256G
  • 500G固态硬盘,分一个200G控件进行源码的存储及编译

准备工作

源码下载

参考:

repo的安装

采用国内镜像安装,具体步骤:

  1. 用户目录下创建bin文件夹,并将~/bin加入到系统的PATH中:

    1
    2
    mkdir ~/bin
    PATH=~/bin:$PATH
  2. 利用清华或科大的镜像来安装repo:

    1
    2
    curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o ~/bin/repo
    chmod a+x ~/bin/repo
  3. 注意修改上述repo文件的REPO_URL值为https://mirrors.tuna.tsinghua.edu.cn/git/git-repo

  4. 切换到你移动硬盘所在的分区(我的分区名字叫Learn),创建源码目录,目录名为aosp,开始同步目录树,这之后就可以进行源码下载了。具体代码如下:

    1
    2
    3
    4
    cd /Volumes/Learn
    mkdir aosp
    cd aosp
    repo sync // 同步Android Source tree

Android源码的下载

执行repo sync -j4就可以开4个线程进行源码同步了,为了防止同步异常,可采用如下shell 脚本来进行异常重试。

  1. 在aosp 目录下新建一个sync.sh脚本文件,其内容如下:
    1
    2
    3
    4
    5
    6
    #!/bin/sh
    repo sync -j4
    while [ $? -ne 0 ]
    do
    repo sync -j4
    done
  2. 更改sync.sh文件的权限:chmod a+x sync.sh

  3. 执行sync.sh文件:./sync.sh

源码编译

1.切换到指定分支

在aosp工作目录,采用以下命令可以查看可以切换的分支:

1
git branch -a | cut -d / -f 3

输出结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
* default
master -> origin
adt_23.0.3
afw-test-harness-1.5
afw-test-harness-2.1
afw-test-harness-marshmallow-dev
afw-test-harness-nougat-dev
android-1.6_r1
android-1.6_r1.1
android-1.6_r1.2
android-1.6_r1.3
android-1.6_r1.4
android-1.6_r1.5
android-1.6_r2
android-10.0.0_r1
android-10.0.0_r2
android-10.0.0_r3
android-10.0.0_r4
android-10.0.0_r5
android-2.0.1_r1
android-2.0_r1
...

2.初始化指定分支代码(如android-6.0.0_r11)

1
2
3
4
5
6
7
8
// 切换到 android-6.0.0_r11 分支
repo init -b android-6.0.0_r11
// 同步该分支的代码
repo sync
// 全部切换到该分支
repo start android-6.0.0_r11 --all
// 查看当前分支
repo branches

3.初始化环境

在aosp(源码根目录)下,执行. /build/envsetup.sh(获取 source /build/envsetup.sh)

注意:这里的.或source 指的是bash的内部命令:source命令,而不是只源码的根路径,我编译源码的时候理解从根路径了,然后运行lunch一直提示找不到lunch命令。

补充:source命令讲解

source命令也称为“点命令”,也就是一个点符号(.),是bash的内部命令。
功能:使Shell读入指定的Shell程序文件并依次执行文件中的所有语句
source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。
用法:
source filename 或 . filename
source命令(从 C Shell 而来)是bash shell的内置命令;点命令(.),就是个点符号(从Bourne Shell而来)是source的另一名称。

source filename 与 sh filename 及./filename执行脚本的区别在那里呢?
1.当shell脚本具有可执行权限时,用sh filename与./filename执行脚本是没有区别得。./filename是因为当前目录没有在PATH中,所有”.”是用来表示当前目录的。
2.sh filename 重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell新建的、改变的变量不会被带回父shell,除非使用export。
3.source filename:这个命令其实只是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。

4.运行lunch命令,选择要编译的版本

5.选择要编译的版本后,运行 make -j6,开始编译(-j6表示开启6个job编译)

6.看到如下的输出(文字是绿色的):

1
#### build completed successfully (44:32(mm::ss)) ####

7.运行emulator启动模拟器即可;

8.启动成功则Android源码编译打工告成。

附录

编译错误集锦

参考链接