玩转AOSP源码编译

2023-05-16

整理搬运一下大佬的文章
https://www.bilibili.com/video/BV19f4y1r7E6
http://liuwangshu.cn/batcoder/aosp/3-compiling-aosp.html

1. 前言

1.1 repo

安卓源码包含数百个git库, googole开发了 repo工具来管理安卓版本库。
repo 使用python对git进行了封装。

1.2 内核源码

AOSP源码中不包含内核源码,需要单独下载。

  1. common 通用的 linux内核源码
  2. msm 用于高通 MSM芯片的 linux内核源码
  3. goldfish 是用于安卓虚拟机的 linux内核源码

1.3 编译AOSP 能做什么

  1. 定制 Android 系统
  2. 将 Android 系统 刷入设备
  3. 将整个系统源码导入到 Android Studio 中
  4. 动态调试 Android 系统源码

其中第三条和第四条也可以不用编译源码来实现,
第三条

  • 只要有对应 Android 源码版本的 android.iml 和 android.ipr 两个文件就可以将源码导入到 Android Studio 中

第四条

  • 动态调试系统源码不一定非要导入整个系统源码进行调试。关于第三条和第四条的具体内容,我会在以后的内容中进行讲解。

2. 编译系统概述

了解以下一些概念,会对 Android 编译系统有大概的了解。
Makefile
Android 平台的编译系统,其实就是用 Makefile 写出来的一个独立项目。它定义了编译的规则,实现了 “自动化编译”,不仅把分散在数百个 Git 库中的代码整合起来、统一编译, 而且还把产物分门别类地输出到一个目录,打包成手机 ROM,还可以生成应用开发时所使用的 SDK、NDK 等。
因此,采用 Makefile 编写的编译系统,也可以称为 Makefile 编译系统。
Android.mk
Makefile 编译系统的一部分,Android.mk 是 android 编译环境下的一种特殊的 “makefile” 文件, 它是经过了 android 编译系统处理的。Android.mk 中定义了一个模块的必要参数,使模块随着平台编译。通俗来讲就是告诉编译系统,以什么样的规则编译你的源代码,并生成对应的目标文件。

Ninja
Ninja 是一个致力于速度的小型编译系统,如果把其他的编译系统看作高级语言,那么 Ninja 目标就是汇编。使用 Ninja 主要目的就是因为其编译速度快。

Soong
Soong 是谷歌用来替代此前的 Makefile 编译系统的替代品,负责解析 Android.bp 文件,并将之转换为 Ninja 文件

Blueprint
Blueprint 用来解析 Android.bp 文件翻译成 Ninja 语法文件。

kati
kati 是谷歌专门为了 Android 而开发的一个小项目,基于 Golang 和 C++。 目的是把 Android 中的 Makefile,转换成 Ninja 文件。

Android.bp
Android.bp,是用来替换 Android.mk 的配置文件。

关系图
Android.mk、Ninja、Soong、Blueprint、kati、Android.bp 的概念之间的联系为:

Blueprint 负责解析 Android.bp 文件内容,Blueprint 类似一个处理相关语法的库文件,Soong 则是定义具体如何处理相应的语法以及命令实现。通俗来讲就是 Soong 借助于 Blueprint 定义的 Android.bp 语法,完成 Android.bp 的解析,最终转换成 Ninja 文件。
Makefile 文件会通过 kati 转换为 Ninja 文件。
随着 Android 工程越来越大,采用 Makefile 的编译系统花费的时间也越来越长,因此谷歌在 Android 7.0 开始引入了 Ninja 来编译系统,相对于 Makefile 来说 Ninja 在大的项目管理中速度和并行方面有突出的优势。
Makefile 默认文件名为 Makefile 或 makefile,也常用. make 或. mk 作为文件后缀。 Ninja 的默认文件名是 build.ninja,其它文件以. ninja 为后缀。Makefile 与 Ninja 的区别在于, Makefile 是设计来给开发编写的,而 Ninja 设计出来是给其它程序生成的。如果 Makefile 是 Java 语言,那么 Ninja 就是汇编语言。

3. 编译源码的方式

Androd 系统源码编译有很多种方式,主要有以下几种:

  • 在 Linux 中直接进行系统源码编译(Android 官方支持)
  • 在 Mac OS 中直接进行系统源码编译(Android 官方支持)
  • 使用 Docker 编译,支持 Mac OS 和 Windows

其中需要注意的是,Docker 的最低支持版本为 Windows7,建议用 Windows10 环境下使用 Docker,因为在 Windows7 中还需要借助 Docker Toolbox 和 VirtualBox 中的容器进行通信,效率相对低些。
考虑到大多数人的设备和上手难易程度,本为讲解在 Linux 中直接进行系统源码编译。

4. 准备编译环境


详见 刘望舒的博客 或者晚上的其他博客

5. 源码编译

整编就是编译整个 Android 源码,整编主要有三个步骤,下面分别就行介绍。

5.1 初始化环境

在 AOSP 的根目录,输入如下的命令:

source build/envsetup.sh
make clobber

使用 build 目录中的 envsetup.sh 脚本初始化环境,这个脚本会引入其他的执行脚本。make clobber 用于清除缓存。

5.2 选择编译目标

输入命令:

lunch

lunch 命令是 envsetup.sh 里定义的一个命令,用来让用户选择编译目标。
会有以下信息输出:

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
     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_mips64-eng
     14. m_e_mips-userdebug
     15. mini_emulator_x86_64-userdebug
     16. mini_emulator_x86-userdebug
     17. uml-userdebug
     18. aosp_cf_x86_auto-userdebug
     19. aosp_cf_x86_phone-userdebug
     20. aosp_cf_x86_tablet-userdebug
     21. aosp_cf_x86_tablet_3g-userdebug
     22. aosp_cf_x86_tv-userdebug
     23. aosp_cf_x86_wear-userdebug
     24. aosp_cf_x86_64_auto-userdebug
     25. aosp_cf_x86_64_phone-userdebug
     26. aosp_cf_x86_64_tablet-userdebug
     27. aosp_cf_x86_64_tablet_3g-userdebug
     28. aosp_cf_x86_64_tv-userdebug
     29. aosp_cf_x86_64_wear-userdebug
     30. cf_x86_auto-userdebug
     31. cf_x86_phone-userdebug
     32. cf_x86_tablet-userdebug
     33. cf_x86_tablet_3g-userdebug
     34. cf_x86_tv-userdebug
     35. cf_x86_wear-userdebug
     36. cf_x86_64_auto-userdebug
     37. cf_x86_64_phone-userdebug
     38. cf_x86_64_tablet-userdebug
     39. cf_x86_64_tablet_3g-userdebug
     40. cf_x86_64_tv-userdebug
     41. cf_x86_64_wear-userdebug
     42. aosp_marlin-userdebug
     43. aosp_marlin_svelte-userdebug
     44. aosp_sailfish-userdebug
     45. aosp_walleye-userdebug
     46. aosp_walleye_test-userdebug
     47. aosp_taimen-userdebug
     48. hikey-userdebug
     49. hikey64_only-userdebug
     50. hikey960-userdebug

Which would you like? [aosp_arm-eng]

意思就是要你选择编译目标的格式,编译目标的格式组成为 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 /ˈneksəs/ 设备,只想编译完后运行在模拟器查看,那么 BUILD 可以选择aosp_x86,BUILDTYPE 选择 eng,Which would you like? [aosp_arm-eng]后面直接输入对应序号 5 就可以。

也可以直接指定编译的目标:

lunch aosp_x86-eng

或者(不同的系统版本,序号的对应会有差别,建议不要直接用序号)

lunch 5

5.3 开始编译

通过 - jN 参数来设置编译的并行任务数,以提高编译速度,在此前我的 CPU 核心数为 6,这里 N 值最好选在 6 到 12 之间,这里我们设置 6 个并行任务进行编译:

make -j6

整编成功后会打印类似如下内容:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OkBwZao3-1632147298206)(https://s2.ax1x.com/2019/05/27/VZWpSs.png)]

由于采用的是虚拟机整编,编译速度会慢一些,这里花费了 2 小时 46 分钟.
最终会在 out/target/product/generic_x86 / 目录生成了三个重要的镜像文件: 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。

5.4 运行模拟器

在编译完成之后, 就可以通过以下命令运行 Android 虚拟机了,命令如下:

source build/envsetup.sh
lunch aosp_x86-eng
emulator

如果是在编译完后运行虚拟机,由于之前已经执行过 source 和 lunch 命令了,可以直接运行:

emulator

如果不出意外就会启动模拟器,如果出现报错,网上也有很多的解决方案。

6. 源码单编

比如我们要编译系统的 Settings 应用模块,
在 AOSP 根目录执行:

source build/envsetup.sh
lunch aosp_x86-eng

进入 Settings 的目录:

cd packages/apps/Settings

mm 编译当前目录下的模块,不编译依赖模块。

mm

编译成功后会有提示生成文件的存放路径。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LydJOtk4-1632147298208)(https://s2.ax1x.com/2019/05/27/VZW9ln.png)]

除了 Settings.odex 文件,还会在 out/target/product/generic_x86/system/priv-app/Settings 目录下生成 Settings.apk。

此外还有以下命令可以进行单编:

  • mmm:编译指定目录下的模块,不编译它所依赖的其它模块。
  • mma:编译当前目录下的模块及其依赖项。
  • mmma:编译指定路径下所有模块,并且包含依赖。

如果你修改了源码,想查看生成的 APK 文件,有两种方式:

  1. 通过 adb push 或者 adb install 来安装 APK。
  2. 使用 make snod 命令,重新生成 system.img,运行模拟器查看。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

玩转AOSP源码编译 的相关文章

随机推荐

  • 如何求一个数二进制1的个数

    思路 xff1a 方法1 xff1a 可以先求二进制的样式 xff0c 再计算其中1的个数 求二进制就是不断对2除和取余 xff0c 余数组成二进制 xff0c 除的结果做下次对2除和取余 xff0c 直到数字为0 方法2 xff1a 可以
  • BLE5.0蓝牙通信原理及TI BLE协议栈在CC2642上的应用

    蓝牙可以分为经典蓝牙和低功耗蓝牙 xff0c 本文重点介绍低功耗蓝牙 xff08 BLE 一 BLE协议栈结构 以TI的CC26XX芯片为例 xff0c BLE协议栈可以由如下图所示部分组成 xff1a 1 物理层 xff1a 物理层是BL
  • RS232/RS485/CAN_BUS 通信原理总结与通信波形分析

    分析一 xff1a 232串口信号 要点 xff1a RS232 xff0c 全双工 xff0c 采用三线制传输分别为TXD RXD GND xff0c 其中TXD为发送信号 xff0c RXD为接收信号 在RS232中任何一条信号线的电压
  • SVN 拉取分支(Branch/tag)和SVN合并(Merge)

    合并 xff08 Merge xff09 例子 xff1a 把对feature branch project name v3 3 7 branch的修改合并到develop 步骤1 xff1a 如图 xff0c 右键目标文件夹 xff0c
  • 宏#define的三种基本定义方式:固定值,表达式,运算符。

    define xff1a define是C语言中的预处理命令 xff0c 预处理命令以 开头 xff0c 比如我们经常写的代码 include lt stdio h gt 也是预处理命令 define用于宏定义 xff0c 作用是方便程序段
  • 四旋翼飞行器的姿态解算小知识点

    1 惯性测量单元IMU InertialMeasurement Unit 姿态航向参考系统AHRS Attitude and Heading Reference System 地磁角速度重力MARG Magnetic Angular Rat
  • 四元数姿态解算中的地磁计融合解读

    笔者最近在做四轴 xff0c 涉及到地磁计的融合算法 xff0c 网上大多数是x IMU的融合代码 xff0c 但是这段代码对于地磁计的融合说明没有做过多的解释 xff0c 网上没有相关讨论 xff0c 仅在阿莫论坛看到一篇相关的代码解释
  • C++封装静态链接库及使用

    一 为什么要把程序封装成库 有时我们需要把自己的程序交给第三方调用 xff0c 但是又不想被别人看到自己的具体实现代码 xff0c 就封装成库给别人使用 库有动态链接库和静态链接库 xff0c 区别是动态链接库可以在程序运行时动态链接 xf
  • 四元数姿态的梯度下降法推导和解读

    笔者前面几篇文章讨论的是基于四元数的互补滤波算法 xff0c 并单独对地磁计融合部分做了详细的讨论和解释 而本文讨论的姿态融合算法叫做梯度下降法 xff0c 这部分代码可以参见Sebastian O H Madgwick在2010年4月发表
  • 四轴加速度计滤波

    加速度计滤波实验参数 xff1a 采样频率Fs 61 250Hz 截止频率Cutoff Frequency 未开电机静止 开电机悬停 未开电机转动飞控 原始输出 Raw 260 Hz 260Hz 260Hz MPU6050内部 LPF 94
  • Kalman论文笔记

    笔者前段时间阅读了一些关于Kalman的姿态论文 xff0c 本想把Kalman的知识点也整理出来发布 xff0c 无奈这编辑器不给力 xff0c 太多的公式无法复制粘贴 xff0c 图片格式上传的太复杂 xff0c 就放弃了 因此笔者只发
  • uCOS-III学习笔记

    前一段时间笔者学习uCOS III xff0c 第一次接触OS这个概念吧 下面把个人的学习笔记分享出来 xff0c 仅供参考 1 前后台系统 xff1a 后台程序是一个死循环 xff0c 也称为 任务级 xff0c 前台程序则是中断服务程序
  • 3.17 开发一个插件

    打开动态链接库 void dlopen const char filename int flag 返回一个操作句柄void Handle 61 dlopen libct so RTLD LAZY RTLD LAZY xff1a 解析动态库遇
  • 5.7 属性声明

    5 7 属性声明 主要用途 使用 attribute 来声明变量 函数的特殊属性 指导编译器来进行特定方面的优化或代码检查 使用方法 在声明后面添加 xff1a attribute ATTRIBUTE 例 xff1a int global
  • 8.18 模块设计原则:高内聚低耦合

    8 18 模块设计原则 xff1a 高内聚低耦合 模块内聚 定义 xff08 软考 xff09 块内联系 xff1a 模块内各元素的关联 交互程度 从功能角度 xff1a 自己的功能自己实现 xff0c 不麻烦其它模块 如何实现高内聚 功能
  • 9.12 中断(下):中断函数的编写

    9 12 中断 下 xff1a 中断函数的编写 中断特性 可随时打断正在执行的任务 可在任何地方打断正在执行的任务 中断返回后 xff0c CPU不一定重新执行被打断的任务 中断函数 调用时间不固定 xff1a 中断要自己保护现场 调用地点
  • 9.16 内存、外存与外设

    9 16 内存 外存与外设 按速度排列 寄存 缓存 内存 外存 存储分类 内存 又称主存 xff1a CPU能直接寻址的存储空间 存取速度快 包括 xff1a RAM ROM cache等 外存 又称辅存 xff1a 除CPU缓存和内存以外
  • 载波相位测量原理

    1 重建载波 定义 xff1a 载波调制了电文之后变成了非连续的波 xff0c 将非连续的载波信号恢复成连续的载波信号 码相关法 xff1a 方法 将所接收到的调制信号 xff08 卫星信号 xff09 与接收机产生的复制码相乘 技术要点
  • wpa_suplicant 详解 文章收集

    wpa suplicant 详解 文章收集 参考资料 https w1 fi wpa supplicant devel index html https zhuanlan zhihu com p 24246712 https www cnb
  • 玩转AOSP源码编译

    整理搬运一下大佬的文章 https www bilibili com video BV19f4y1r7E6 http liuwangshu cn batcoder aosp 3 compiling aosp html 1 前言 1 1 re