Android源码之下载编译导入AS(Mac版)

image

Android源码之下载编译导入AS(Mac版)

AOSP源码下载和编译

环境准备

官方指南:

要求

搭建编译环境

推荐准备250G可用磁盘空间。

创建分区大小写的磁盘映像

Mac OS默认会在不区分大小写的文件系统中运行,但由于Git并不支持此类文件系统,所以需要在Mac OS上建立一个区分大小写的磁盘分区。我们这里使用命令行来创建,一是比较方便,二是后期可扩展。

您可以使用磁盘映像在现有的 Mac OS 环境中创建区分大小写的文件系统。要创建磁盘映像,请启动磁盘工具,然后选择“新建映像”。这里推荐准备250G的磁盘空间;更大的空间能够更好地满足未来的需求。使用稀疏映像有助于节省空间,而且以后可以随着需求的增加进行扩展。请务必选择“Case sensitive, Journaled”存储卷格式。

您也可以通过 shell 使用以下命令创建磁盘映像:

$ hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 250g ~/android.dmg

这将创建一个 .dmg(也可能是 .dmg.sparseimage)文件,该文件在装载后可用作具有 Android 开发所需格式的存储卷。

如果您以后需要更大的存储卷,还可以使用以下命令来调整稀疏映像的大小:

$ hdiutil resize -size g ~/android.dmg.sparseimage

比如需要把250G调整成300G:

$ hdiutil resize -size 300g ~/android.dmg.sparseimage

注意:调整分区大小的命令,需要在该分区磁盘映像已卸载的情况下才能生效。

添加装载和卸载磁盘分区的命令和函数

对于存储在当前用户目录下的名为 android.dmg 的磁盘映像,您可以向 ~/.bash_profile 中添加辅助函数:

# mount the android file image
function mountAndroid { hdiutil attach ~/android.dmg -mountpoint /Volumes/android; }

注意:如果系统创建的是 .dmg.sparseimage 文件,请将 ~/android.dmg 替换成 ~/android.dmg.sparseimage

需要装载分区磁盘映像时,执行如下命令即可,装载路径为/Volumes/android

$ mountAndroid

同样,卸载的函数如下,我们也将它添加到~/.bash_profile文件中:

# unmount the android file image
function umountAndroid() { hdiutil detach /Volumes/android; }

执行如下命令,便可卸载该分区磁盘映像:

$ umountAndroid

安装JDK

如果Mac已经安装JDK且配好了环境变量,可省略这步。

要查看在开发各种 Android 版本时要使用的 Java 版本,请参阅相关要求。

安装Xcode和其他软件包

1.安装Xcode命令行工具:

$ xcode-select --install

2.安装Xcode,直接在AppStore里安装即可。

3.安装MacPorts或Homebrew,MacPorts和Homebrew是软件包管理工具,可用来直接在终端里安装、更新和卸载软件包。建议二者都安装,笔者在通过MacPorts安装gnupg时死活装不上,最后通过Homebrew安装成功,如果网页访问不了,请翻墙。

4.在~/.bash_profile文件中导入路径,就可以使用port或brew命令来管理软件包了:

export PATH=/opt/local/bin:$PATH
export PATH=/usr/local/bin:$PATH

5.安装gmake、libsdl、git和gnupg

  • 如果是使用MacPorts,则执行如下命令:
$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg
  • 如果是使用Homebrew,则执行如下命令:
$ brew install gmake libsdl git gnupg2

设置文件描述符数量上限

在 Mac OS 中,可同时打开的文件描述符的默认数量上限太低,在高度并行的编译流程中,可能会超出此上限。要提高此上限,请将下列行添加到 ~/.bash_profile 中:

# set the number of open files to be 1024
ulimit -S -n 1024

至此,一切准备工作就绪,接下来就是下载源码了。

下载源码

官方教程,由于有墙的原因,下载过程中可能会出现各种问题,这里推荐使用清华大学镜像站来下载。

下载安装Repo工具

由于Android源码庞大复杂,所以Google专门开发了Repo来管理Android源码库,这里不多作介绍,有兴趣可自行阅读repo工具介绍。

按照官方建议,首先在用户主目录下有一个 bin/ 目录,并且将该目录包含在路径中:

$ mkdir ~/bin
$ PATH=~/bin:$PATH

然后下载Repo工具,并确保它可执行:

$ curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo
$ chmod a+x ~/bin/repo

初始化Repo客户端

在前面,我们通过mountAndroid命令装载了我们分区后的磁盘映像,其装载路径为/Volumes/android,所以我们需要在该目录下进行初始化,切换到该目录下,并且创建一个aosp的工作目录:

$ cd /Volumes/android/
$ mkdir aosp
$ cd aosp

现在,我们的源码根目录全路径为/Volumes/android/aosp

Repo的运行过程中会尝试访问官方的git源更新自己,如果想使用清华的镜像源进行更新,可以将如下内容复制到你的~/.bashrc(没有该文件则创建一个)里:

export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'

然后配置git,需要姓名和邮箱(如果已经配置过,不需要再配置):

$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"

运行repo init来初始化master分支:

$ repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest

要对master以外的分支进行校验,请使用 -b 来指定相应分支。要查看分支列表,请参阅源代码标记和版本,笔者这里指定的是android-9.0.0_r35分支:

$ repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-9.0.0_r35

下载源代码

在终端进入/Volumes/android/aosp源码根目录下,输入下面命令来同步代码:

$ repo sync

下载源代码的过程很漫长,期间可能会因为网络等原因,导致下载出错,因为repo同步支持断点续传,所以这里推荐使用shell脚本下载:

在源码根目录下创建一个reposync.sh脚本文件,脚本内容如下:

#!/bin/bash   
#FileName  reposync.sh  
PATH=~/bin:$PATH   
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-9.0.0_r35
repo sync   
while [ $? = 1 ]; do   
echo "================sync failed, re-sync again ====="   
sleep 3   
repo sync   
done

保存好后,在源码根目录下的执行下面命令:

$ ./reposync.sh

这样就开始下载了,等待...

由于下载过程漫长,建议将Mac节能设置成防止进入睡眠。

当下载完成会提示:

Syncing work tree: 100%(xxx/xxx), done.

编译

编译命令还是在源码根目录下进行:/Volumes/android/aosp

初始化编译环境

使用envsetup.sh脚本初始化环境:

$ source build/envsetup.sh

选择编译目标

使用lunch选择编译目标:

$ lunch 

You're building on Darwin

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_arm64-eng
     3. aosp_mips-eng
     4. aosp_mips64-eng
     5. aosp_x86-eng
     6. aosp_x86_64-eng
     7. aosp_car_arm-userdebug
     8. aosp_car_arm64-userdebug
     9. aosp_car_x86-userdebug
     10. aosp_car_x86_64-userdebug
     11. mini_emulator_arm64-userdebug
     12. m_e_arm-userdebug
     13. m_e_mips-userdebug
     14. m_e_mips64-eng
     15. mini_emulator_x86-userdebug
     16. mini_emulator_x86_64-userdebug
     17. uml-userdebug
     18. aosp_crosshatch-userdebug
     19. aosp_blueline-userdebug
     20. aosp_cf_x86_auto-userdebug
     21. aosp_cf_x86_phone-userdebug
     22. aosp_cf_x86_tablet-userdebug
     23. aosp_cf_x86_tablet_3g-userdebug
     24. aosp_cf_x86_tv-userdebug
     25. aosp_cf_x86_wear-userdebug
     26. aosp_cf_x86_64_auto-userdebug
     27. aosp_cf_x86_64_phone-userdebug
     28. aosp_cf_x86_64_tablet-userdebug
     29. aosp_cf_x86_64_tablet_3g-userdebug
     30. aosp_cf_x86_64_tv-userdebug
     31. aosp_cf_x86_64_wear-userdebug
     32. cf_x86_auto-userdebug
     33. cf_x86_phone-userdebug
     34. cf_x86_tablet-userdebug
     35. cf_x86_tablet_3g-userdebug
     36. cf_x86_tv-userdebug
     37. cf_x86_wear-userdebug
     38. cf_x86_64_phone-userdebug
     39. cf_x86_64_tablet-userdebug
     40. cf_x86_64_tablet_3g-userdebug
     41. cf_x86_64_tv-userdebug
     42. cf_x86_64_wear-userdebug
     43. aosp_marlin-userdebug
     44. aosp_marlin_svelte-userdebug
     45. aosp_sailfish-userdebug
     46. aosp_walleye-userdebug
     47. aosp_walleye_test-userdebug
     48. aosp_taimen-userdebug
     49. hikey-userdebug
     50. hikey64_only-userdebug
     51. hikey960-userdebug

Which would you like? [aosp_arm-eng]

这里列出了所有的可编译的目标,所有编译目标都采用 BUILD-BUILDTYPE 形式。

BUILD

BUILD表示特定功能的组合名称,即编译出的镜像可以在什么环境上运行,其中aosp(Android Open Source Project)代表Android开源项目,arm表示系统是运行在arm架构的处理器上,arm64则是指64位arm架构;处理器,x86则表示x86架构的处理器;此外,还有一些单词代表了特定的Nexus设备,下面是常用的设备代码和编译目标,更多参考官方文档

受型号 设备代码 编译目标
Nexus 6P angler aosp_angler-userdebug
Nexus 5X bullhead aosp_bullhead-userdebug
Nexus 6 shamu aosp_shamu-userdebug
Nexus 5 hammerhead aosp_hammerhead-userdebug

BUILDTYPE

BUILDTYPE表示编译类型,一般有三种:

编译类型 含义
user 表示编译出的系统镜像是可以用来正式发布到市场的版本,其权限是被限制的(如:没有root权限,不能dedug等)
userdebug 在user版本的基础上开放了root权限和debug权限
eng 表示engineer,也就是所谓的开发工程师的版本,拥有最大的权限(root等),此外还附带了许多debug工具

如果你有Pixel或Nexus真机,选择对应的编译目标即可,否则我们就选模拟器,即5.aosp_x86-eng

在上面的Which would you like? [aosp_arm-eng]后面输入5即可。也直接选择:

$ lunch 5

$ lunch aosp_x86-eng

编译代码

在编译之前,可以输入以下命令,查看你的Mac CPU核数:

$ sysctl -n machdep.cpu.core_count
4

输出为4核,我们就可以启动4个线程来编译源码:

$ make -j4

接下来就是漫长的编译过程,一般需要2~3小时,如果看到下面的提示,则表示编译完成:

#### build completed successfully (02:15:52 (hh:mm:ss)) ####

运行模拟器

在编译完成之后,在终端里输入以下命令,可使用模拟器运行编译出的镜像:

$ emulator

如果想要模拟器能联网的话,可以这样启动模拟器:

$ emulator -dns-server 8.8.8.8,114.114.114.114

如果终端关闭了,下次进入源码根目录时想要启动模拟器,需要这样做:

$ source build/envsetup.sh
$ lunch aosp_x86-eng
$ emulator -dns-server 8.8.8.8,114.114.114.114

AOSP源码导入AS

编译idegen模块

在源码根目录下使用下面命令编译idegen模块:

$ mmm development/tools/idegen/

编译完成后有如下提示:

#### build completed successfully (02:14 (mm:ss)) ####

继续执行下面命令,会在源码根目录下生成android.iprandroid.iml IDEA工程配置文件:

$ development/tools/idegen/idegen.sh
Read excludes: 26ms
Traversed tree: 118715ms

注意:对于平常看源码调试源码来说AOSP源码整体编译一遍就可以了,目前我们用到的单编就是上面所说的idegen模块,如果我们在源码导入AS的过程中出现了android.ipr/android.iml文件以及随后导入AS自动生成的android.iws文件损坏情况,我们只需在AOSP源码根目录下找到这三个文件删掉,然后重复上面的步骤重新生成一下就行了。

精简android.iml文件

android源码在一个类文件中点击类名能够跳转到另一个类文件依赖的就是android.iml文件中的配置,但是默认生成的android.iml文件中导入了太多不必要的代码,直接导入AS会导致indexing很长时间,我们可以精简一部分,比如测试类的文件,它们在android.iml文件中都有这么一个特征,以开头,以isTestSource="true"/>结尾,所以,我们可以用VSCode打开android.iml文件,然后用VSCode的文本替换功能把以开头isTestSource="true"/>结尾的行替换成空格,所有被替换的文件都不会导入AS,加快了indexing速度。

因为以开头isTestSource="true"/>结尾的行太多了,我们不可能一行行的删,怎么办呢?使用正则表达式匹配这些行。

我们使用VSCode的文本替换功能,然后在匹配栏输入(前提把匹配栏切换成支持正则表达式),这时候你会发现所有匹配上的行都高亮显示了,然后在替换栏输入空格,点击替换按钮就会一键替换完成,然后保存。

导入源码

我们在AOSP源码目录下找到上面生成的android.ipr文件,然后鼠标右键选择“打开方式”,找到Android Studio,然后打开,如果遇到convert一类的提示,千万不要convert,因为convert之后,你的android.iml文件标签中的属性会发生变化,导致的结果就是Source Folders识别不出你导入了哪些文件夹。

然后就等待吧,直到AS indexing完成...

接下来,我们需要看看源码有没有导入成功,怎么判断成没成功呢?

我们打开AS上的Project Structure按钮,如图:

image

然后出现下面这个界面:

image

Source Folders里面出现了很多类似于上图中的蓝色路径,那恭喜你,源码导入成功了(由于导入的源码太多,你可能在打开上述页面时会非常卡顿)。

导入源码成功之后,我们就需要一些配置才能更方便的阅读源码和调试。

第一步:配置一个Module SDK,如下图。

image

我们在Project Structure页面中点开SDKs,然后点击+号添加一个名为1.8 (No Libraries)的SDK,JDK home path可以选择Android Studio自带的JDK home目录,也可以选择Mac上已安装的JDK home目录,无所谓,最重要的一点来了,就是要把上图中的ClasspathSourcepath中的依赖删除干净,一个不留,这里说一下ClasspathSourcepath的意义:

Classpath:表示项目依赖的类,一般是jar包;

Sourcepath:表示依赖的这些类的源代码目录,如果没有设置Sourcepath,我们在项目中跳转到这些依赖的类时,看到的是字节码文件反编译后的Java代码,没有任何的代码注释,但设置了Sourcepath,就是跳转到Sourcepath中的源代码,是有注释的,一般Classpath中的jar包是由Sourcepath中的源代码打成jar包得来的。

第二步:配好了Module SDK后,我们需要把它引用到AOSP源码中。

image

我们在Project Structure界面点击Modules,然后在1处选择我们刚刚配置的1.8 (No Libraries)sdk,然后2处就有了这个sdk的引用,你会发现这个引用是没有-删除按钮的,这就意味着你必须选择一个Module SDK引用,但是AOSP源码中的所有代码都比较完全,没有必要去引用其他的依赖,所以我们前面配置了一个没有任何依赖的Module SDK供源码引用(删除了所有的ClasspathSourcepath中的依赖)。

第三步:最后也是很重要的一步,没有这一步,看源码是没有问题的,但是想要调试就不行了。

image

还是在Project Structure界面中点击Project,然后画红框部分选择一个Android SDK,最好是和AOSP源码版本对应的SDK。

最后,点击ApplyOK,完成设置,等待一会indexing后就可以愉快的看源码了。

你可能感兴趣的:(Android源码之下载编译导入AS(Mac版))