01 前言
在上一篇【Android-源码下载】中,我们成功下载了源码,现在我们在同样的Linux环境下将源码进行编译。
02 课前知识
1. 如何查看下载的源码是那个版本的?
在源码根目录aosp下
cat build/core/version_defaults.mk #查看版本信息
找到PLATFORM_SDK_VERSION
ifndef PLATFORM_SDK_VERSION
# This is the canonical definition of the SDK version, which defines
# the set of APIs and functionality available in the platform. It
# is a single integer that increases monotonically as updates to
# the SDK are released. It should only be incremented when the APIs for
# the new release are frozen (so that developers don't write apps against
# intermediate builds). During development, this number remains at the
# SDK version the branch is based on and PLATFORM_VERSION_CODENAME holds
# the code-name of the new development work.
# When you increment the PLATFORM_SDK_VERSION please ensure you also
# clear out the following text file of all older PLATFORM_VERSION's:
# cts/tests/tests/os/assets/platform_versions.txt
PLATFORM_SDK_VERSION := 30
endif
可以看到源码版本是 PLATFORM_SDK_VERSION := 30,也就是最新的Android 11;
03 编译环境准备
1. 安装jdk 8
sudo apt-get update
sudo apt-get install openjdk-8-jdk
2. 安装其他必须的依赖包
这里推荐去看【官方文档】,不同版本的Ubuntu环境,需要的依赖包不同
安装所需的软件包 (Ubuntu 18.04)
sudo apt-get install git-core gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig
安装所需的软件包(建议使用 Ubuntu 14.04)
sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev libgl1-mesa-dev libxml2-utils xsltproc unzip
04 开始编译
现在就可以进行编译了,分为两种:全编和模块单编译
1. 源码全编
a. 初始化环境,输入如下命令:
source build/envsetup.sh
b. 选择目标进行编译,输入如下命令:
lunch
lunch之后会有很多版本可以进行选择
Lunch menu... pick a combo:
1. aosp_arm-eng
2. aosp_arm64-eng
3. aosp_blueline-userdebug
4. aosp_blueline_car-userdebug
5. aosp_bonito-userdebug
6. aosp_bonito_car-userdebug
7. aosp_bramble-userdebug
8. aosp_car_arm-userdebug
9. aosp_car_arm64-userdebug
10. aosp_car_x86-userdebug
11. aosp_car_x86_64-userdebug
12. aosp_cf_arm64_auto-userdebug
13. aosp_cf_arm64_phone-userdebug
14. aosp_cf_x86_64_phone-userdebug
15. aosp_cf_x86_auto-userdebug
16. aosp_cf_x86_phone-userdebug
17. aosp_cf_x86_tv-userdebug
18. aosp_coral-userdebug
19. aosp_coral_car-userdebug
20. aosp_crosshatch-userdebug
21. aosp_crosshatch_car-userdebug
22. aosp_flame-userdebug
23. aosp_flame_car-userdebug
24. aosp_redfin-userdebug
25. aosp_sargo-userdebug
26. aosp_sunfish-userdebug
27. aosp_trout_arm64-userdebug
28. aosp_trout_x86-userdebug
29. aosp_x86-eng
30. aosp_x86_64-eng
31. arm_krait-eng
32. arm_v7_v8-eng
33. armv8-eng
34. armv8_cortex_a55-eng
35. armv8_kryo385-eng
36. beagle_x15-userdebug
37. beagle_x15_auto-userdebug
38. car_x86_64-userdebug
39. db845c-userdebug
40. fuchsia_arm64-eng
41. fuchsia_x86_64-eng
42. hikey-userdebug
43. hikey64_only-userdebug
44. hikey960-userdebug
45. hikey960_tv-userdebug
46. hikey_tv-userdebug
47. pixel3_mainline-userdebug
48. poplar-eng
49. poplar-user
50. poplar-userdebug
51. qemu_trusty_arm64-userdebug
52. silvermont-eng
53. uml-userdebug
54. yukawa-userdebug
55. yukawa_sei510-userdebug
这里简单解释一下这些名字的意义:
编译目标的格式组成为BUILD-BUILDTYPE,比如aosp_arm-eng的BUILD为aosp_arm,BUILDTYPE为eng。
其中BUILD表示编译出的镜像可以运行在什么环境,aosp代表Android开源项目,arm表示系统是运行在arm架构的处理器上。
更多参考【官方文档】。
BUILDTYPE 指的是编译类型,有以下三种:
user:用来正式发布到市场的版本,权限受限,如没有root权限,不能 dedug,adb默认处于停用状态。
userdebug:在user版本的基础上开放了 root 权限和 debug 权限,adb默认处于启用状态。一般用于调试真机。
eng:开发工程师的版本,拥有最大的权限(root等),具有额外调试工具的开发配置。一般用于模拟器。
如果你没有Nexus设备,只想编译完后运行在模拟器查看,那么BUILD可以选择aosp_x86,BUILDTYPE选择eng,Which would you like? [aosp_car_x86_64-userdebug]后面直接输入对应序号11就可以。
当然也可以直接选择目标输入:(这里我编译的是车机的版本)
lunch aosp_car_arm64-userdebug # 或者 lunch 9
c. 选好目标版本之后,进行编译命令:
make -j8
Tips:这个-j8参数可加也可以不加,表示提高编译的并行任务数量,根据你的电脑配置进行设置,一般是在设置为你的电脑的内核数量的1~2倍之间。那么如何查看电脑CPU的内核数量呢?输入如下命令:
lscpu
可以看到如下信息:
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
CPU(s): 16
...
所以我编译的时候用的是 -j32,最终的效果如下:
[100% 75048/75048] Create system-qemu.img now
removing out/target/product/emulator_arm64/system-qemu.img.qcow2
out/host/linux-x86/bin/sgdisk --clear out/target/product/emulator_arm64/system-qemu.img
#### build completed successfully (45:20 (mm:ss)) ####
因为我的电脑是一台旧的服务器,所以性能还是比一般的电脑快很多,正常情况的话全编一次应该在3小时左右,第一次全编比较慢,后面就会快很多。最终会在 out/target/product/emulator_arm64/目录生成了三个重要的镜像文件: system.img、userdata.img、ramdisk.img。
简单说下这三个镜像文件:
system.img:系统镜像,里面包含了Android系统主要的目录和文件,通过init.c进行解析并mount挂载到/system目录下。
userdata.img:用户镜像,是Android系统中存放用户数据的,通过init.c进行解析并mount挂载到/data目录下。
ramdisk.img:根文件系统镜像,包含一些启动Android系统的重要文件,比如init.rc。
2. 启动emulator
输入如下命令;正常的话就可以看到模拟器了,如果报错,请百度
emulator
emulator有很多种启动参数可以配置,请参考官方文档【emulator启动参数】
3. 单编译模块
在aosp目录下执行
source build/envsetup.sh
lunch 11
然后进入模块目录,这里我们编译Music
cd packages/apps/Music
执行模块编译命令 mm,编译只编译当前模块,不编译其依赖的模块
mm
最后看结果:
[100% 910/910] Copy: out/target/product/emulator_arm64/system/product/app/MusicKotlin/oat/arm64/MusicKotlin.vdex
#### build completed successfully (01:18 (mm:ss)) ####
在out/target/product/emulator_arm64/system/product/app/MusicKotlin/目录下有apk和oat文件夹
4. 其他编译命令
此外还有以下命令可以进行单编:
mmm:编译指定目录下的模块,不编译它所依赖的其它模块。
mma:编译当前目录下的模块及其依赖项。
mmma:编译指定路径下所有模块,并且包含依赖。
如果你修改了源码,想查看生成的APK文件,有两种方式:
通过adb push或者adb install 来安装APK。
使用make snod命令,重新生成 system.img,运行模拟器查看。
05 感谢参考链接
本文感谢一些博客链接及官方文档
liuwangshu.cn/framework/a…
www.cnblogs.com/WuXiaolong/…
source.android.google.cn/