2.2 Android源码下载及编译流程
之前已经完成了Ubuntu Linux、OpenJDK以及编译Android源码所需的系统工具包的安装和配置,接下来就是下载并编译Android 8.1.0源码了。 这个过程很简单,但需要很长时间。
2.2.1 工作目录设置
Android 8.0的代号为Oreo,简称O,中文名称为奥利奥。 本书使用的Android 8.1.0版本源代码的根目录名为Oreo,并在用户根目录下新建一个代码根目录Oreo文件夹,并将该目录设置为工作目录,并导出 $oreo=~/ 在 .bashrc 代码/Oreo 中降低。
注意
在Android开发过程中,配置工作目录的环境变量有利于提高工作效率,主要是环境变量与工作目录结合使用,比如一些Android工具命令、代码路径、编译结果路径等,将简化操作。 读者可以在使用过程中使用。 渐渐感觉; 后续涉及到的$oreo就是Android 8.1.0源码的根目录路径。
2.2.2 源码下载
Android 8.1.0源码的本地目录已经完成,下一步就是开始下载代码了。 相关操作及说明如下:
repo脚本是Android项目编写的Python脚本,用来统一管理Android项目的代码仓库 $ sudo apt-get install python $ curl https://storage.googleapis.com/git-repo-downloads/repo > repo $ chmod a+x repo
注意
在~/用户主目录下新建bin目录,并将该目录设置在PATH目录中; 我们会在这个目录下保存一些常用的脚本或者二进制可执行程序,以后不用更新系统环境变量就可以在任何目录下执行这个脚本或者可执行程序。
$ mkdir ~/bin $ vi ~/.bashrc //在文件最后一行增加PATH=~/bin:$PATH,保存退出 $ source .bashrc//立即生效配置的PATH目录 $ mv repo ~/bin/ $ cd $oreo //配置git个人信息 $ git config --global user.name android_tele $ git config --global user.email android_tele @163.com //查看配置的git信息 $ cat ~/.gitconfig [user] name = android_tele email = android_tele @163.com [color] ui = auto //获取Android源码分支信息 $ repo init -u https://android.googlesource.com/platform/manifest ...... * [new tag] android-8.0.0_r32 -> android-8.0.0_r32 * [new tag] android-8.0.0_r33 -> android-8.0.0_r33 * [new tag] android-8.0.0_r34 -> android-8.0.0_r34 * [new tag] android-8.0.0_r35 -> android-8.0.0_r35 * [new tag] android-8.0.0_r36 -> android-8.0.0_r36 * [new tag] android-8.0.0_r4 -> android-8.0.0_r4 * [new tag] android-8.0.0_r7 -> android-8.0.0_r7 * [new tag] android-8.0.0_r9 -> android-8.0.0_r9 * [new tag] android-8.1.0_r1 -> android-8.1.0_r1 ...... //读者可根据实际情况,选择最新的Android源码分支下载,本书选择android-8.1.0_r1分支下载 $ repo init -u https://android.googlesource.com/platform/manifest -b android-8.1.0_r1 repo has been initialized in /home/android/Oreo $ repo sync –j8 //开始下载Android O源码,工作进程数量,本例中使用8个,读者可以根据网络带宽进行调整 //这个过程花费的时间很长,视网络情况而定;建议读者在晚上下载,如果中途代码下载中断了,也不必担心, //repo sync支持续传
2.2.3 开始编译Android源码
Android 8.1.0源码下载完成后,就可以开始编译源码了。 具体请参见以下操作及相关说明。
$ cd $oreo $ source build/envsetup.sh //或者. build/envsetup.sh //加载编译脚本 //使用第二种方法需要注意,build前有一个空格 including device/asus/fugu/vendorsetup.sh including device/generic/car/vendorsetup.sh including device/generic/mini-emulator-arm64/vendorsetup.sh ...... including device/huawei/angler/vendorsetup.sh including device/lge/bullhead/vendorsetup.sh including sdk/bash_completion/adb.bash $ lunch //选择编译的产品信息 You're building on Linux 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 ...... 28. aosp_angler-userdebug 29. aosp_bullhead-userdebug 30. aosp_bullhead_svelte-userdebug 31. hikey-userdebug 32. hikey960-userdebug Which would you like? [aosp_arm-eng] aosp_arm64-eng ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=8.1.0 //Android O版本 TARGET_PRODUCT=aosp_arm64 //lunch选择aosp_arm64-eng TARGET_BUILD_VARIANT=eng ...... BUILD_ID=OPM1.171019.011 //编译号 OUT_DIR=out AUX_OS_VARIANT_LIST= ============================================ $ make –j8 //编译时间长,编译过程中输出的日志很大,这里对编译日志进行了省略 //以下是编译成功日志信息,可以看出成功编译出system.img镜像文件 encoding RS(255, 253) to '/tmp/tmpGZPyrs_verity_images/verity_fec.img' for input files: 1: 'out/target/product/angler/obj/PACKAGING/systemimage_intermediates/system.img' 2: '/tmp/tmpGZPyrs_verity_images/verity.img' appending /tmp/tmpGZPyrs_verity_images/verity_fec.img to /tmp/tmpGZPyrs_verity_images/verity.img Running: append2simg out/target/product/angler/obj/PACKAGING/systemimage_intermediates/system.img/tmp/ tmpGZPyrs_verity_images/verity.img [100% 89721/89721] Install system fs image: out/target/product/generic_arm64/system.img out/target/product/angler/system.img+out/target/product/generic_arm64/obj/PACKAGING/ recovery_patch_intermediates/recovery_from_boot.p maxsize=3288637440 blocksize=135168 total=1048456853 reserve=33251328 #### build completed successfully (02:26:35 (hh:mm:ss)) ####
第一次编译时间较长,不同的电脑耗时不同。 笔者使用一台较旧的笔记本电脑(Core 2 Duo i7+8GB)编译Android O源代码,总共使用了6.5小时。 如果计算机的处理能力较强,可以使用更多的工作进程,如:make –j16,以增加编译工作进程的数量android 2.2 编译源码,从而减少编译时间。 编译完成后,进入$oreo/out/target/product/generic_arm64目录,注意该目录下的三个IMG镜像文件system.img、ramdisk.img、userdata.img,以及数据、obj、root、system等目录。 请读者自行检查编译完成后生成了哪些文件。 这里我们重点关注系统目录。 主要目录结构如下。
app/priv-app(应用程序apk文件,如TeleService.apk、Mms.apk等)
bin(可执行文件、app_process32/64、toybox、netd 等)
等(系统配置信息)
字体(字体文件)
Framework(主要保存一些jar包,framework.jar,telephony-common.jar等)
lib/lib64(主要保存一些so动态链接库文件,libbrillo.solibsurfaceflinger.so等)
usr(用户配置信息)
xbin(系统的一些可执行文件)
2.2.4 编译单个模块
整个Android编译环境的搭建已经完成了60%。 上面说了,为什么要搭建这样的编译环境,就是为了调试运行改变的内容。 如果在Telephony应用程序中更改Android源代码以减少日志复制功能android 2.2 编译源码,是否也应该通过make进行编译? 在这种情况下,编译需要花费大量时间。 在Android中,还可以按照模块单独编译模块,这样可以减少不必要的编译时间开销。
注意
在编译子模块之前,必须先完成整体编译,否则需要单独编译的模块无法编译成功。
子模块编译主要有3种方法。 首先是在$oreo代码根目录下执行mmm module path命令; 二是进入相应应用模块代码所在目录,执行mm命令; 第三种是在$oreo代码根目录下执行make module name命令。 具体请参见以下操作及相关说明。
$ cd $oreo $ source build/envsetup.sh //或者. build/envsetup.sh //使用第二种方法需要注意build前有一个空格 $ mmm packages/service/Telephony/ //编译TeleService应用 $ mmm frameworks/base/ //编译framework.jar $ cd packages/service/Telephony //TeleService应用代码目录 $ mm //编译TeleService模块 $ cd $oreo $ cd frameworks/base //进入framework代码目录 $ mm //编译framework $ cd $oreo $ make TeleService //编译TeleService应用 $ make framework //编译framework.jar应用
无论使用哪种方式编译单个模块,编译成功后都会有类似如下的日志。
[100% 10/10] Install: out/target/product/generic_arm64/system/priv-app/TeleService/TeleService.apk #### build completed successfully (01:16 (mm:ss)) #### [100% 131/31] Install: out/target/product/generic_arm64/system/framework/arm64/boot.art #### build completed successfully (05:28 (mm:ss)) ####
注意
建议使用make模块名+mmm的形式按模块编译。 编译过程不涉及目录切换,可以减少工作量。 这两种方法中,首选mmm编译形式,因为它比make模块名称形式更节省时间。