Android-源码编译

3,850 阅读6分钟

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-engBUILDaosp_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/目录下有apkoat文件夹


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/