Android 编译笔记

本文详细记录了Android编译的全过程,从执行编译的命令解析到Makefile的使用,再到编译结果的目录结构和重要镜像文件的生成。重点介绍了如何设置编译环境,如何选择编译目标,以及Build系统的关键文件和目标。编译产物主要分布在/out目录下,包括host工具、target应用和特定设备的编译结果。文章最后提到了Android Build系统的复杂性和相关参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android 编译笔记

执行编译

$ source build/envsetup.sh 
$ lunch
$ make -j8

第一行命令“source build/envsetup.sh”引入了 build/envsetup.sh脚本。该脚本的作用是初始化编译环境,并引入一些辅助的 Shell 函数,这其中就包括第二步使用 lunch 函数。

build/envsetup.sh中定义的常用函数

名称说明
croot切换到源码树的根目录
m在源码树的根目录执行 make
mmBuild 当前目录下的模块
mmmBuild 指定目录下的模块
cgrep在所有 C/C++ 文件上执行 grep
jgrep在所有 Java 文件上执行 grep
resgrep在所有 res/*.xml 文件上执行 grep
godir转到包含某个文件的目录路径
printconfig显示当前 Build 的配置信息
add_lunch_combo在 lunch 函数的菜单中添加一个条目

第二行调用lunch函数,如果调用 lunch 函数的时候没有指定参数,那么该函数将输出列表以供选择,此时可以通过输入编号或者名称进行选择。

     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. aquilac_evb-userdebug
     8. aquilac_evbcmcc-userdebug
     9. aquilac_fpga-userdebug
     10. aquilac_phone-userdebug
     ...

     Which would you like? [aosp_arm-eng] _

第三行命令make -j8才真正开始执行编译。make 的参数-j指定了同时编译的 Job 数量,这是个整数,该值通常是编译主机 CPU 支持的并发线程总数的 1 倍或 2 倍(例如:在一个 4 核,每个核支持两个线程的 CPU 上,可以使用 make -j8make -j16)。在调用 make 命令时,如果没有指定任何目标,则将使用默认的名称为droid目标,该目标会编译出完整的 Android 系统镜像。

Build结果的目录结构

所有的编译产物都将位于 /out 目录下,该目录下主要有以下几个子目录:
+ /out/host/:该目录下包含了针对主机的 Android 开发工具的产物。即 SDK 中的各种工具,例如:emulator,adb,aapt 等。
+ /out/target/common/:该目录下包含了针对设备的共通的编译产物,主要是 Java 应用代码和 Java 库。
+ /out/target/product/[product_name]/:包含了针对特定设备的编译结果以及平台相关的 C/C++ 库和二进制文件。其中,[product_name]是具体目标设备的名称。
+ /out/dist/:包含了为多种分发而准备的包,通过“make disttarget”将文件拷贝到该目录,默认的编译目标不会产生该目录。

Build生成的镜像文件

Build 的产物中最重要的是三个镜像文件,它们都位于 /out/target/product/<product_name>/ 目录下:
+ system.img:包含了 Android OS 的系统文件,库,可执行文件以及预置的应用程序,将被挂载为根分区。
+ ramdisk.img:在启动时将被 Linux 内核挂载为只读分区,它包含了 /init 文件和一些配置文件。它用来挂载其他系统镜像并启动 init 进程。
+ userdata.img:将被挂载为 /data,包含了应用程序相关的数据以及和用户相关的数据

Make文件说明

整个 Build 系统的入口文件是源码树根目录下名称为“Makefile”的文件,当在源代码根目录上调用 make 命令时,make 命令首先将读取该文件。

文件内容

### DO NOT EDIT THIS FILE ###
include build/core/main.mk
### DO NOT EDIT THIS FILE ###                           

该行代码的作用很明显:包含 build/core/main.mk 文件。在 main.mk 文件中又会包含其他的文件,其他文件中又会包含更多的文件,这样就引入了整个 Build 系统。

具体内容可以对照Make文件说明查阅。

这里只列出几个重要的make文件解释

  • config.mk, 整个 Build 系统的配置文件,最重要的 Make 文件之一,该文件中主要包含以下内容:
    • 定义了许多的常量来负责不同类型模块的编译。
    • 定义编译器参数以及常见文件后缀,例如 .zip,.jar.apk。
    • 根据 BoardConfig.mk 文件,配置产品相关的参数。
    • 设置一些常用工具的路径,例如 flex,e2fsck,dx。
  • definitions.mk
    • 最重要的 Make 文件之一,在其中定义了大量的函数。这些函数都是 Build 系统的其他文件将用到的。例如:my-dir,all-subdir-makefiles,find-subdir-files,sign-package 等,关于这些函数的说明请参见每个函数的代码注释。

Android 源码中包含了许多的模块,模块的类型有很多种,例如:Java 库,C/C++ 库,APK 应用,以及可执行文件等 。并且,Java 或者 C/C++ 库还可以分为静态的或者动态的,库或可执行文件既可能是针对设备(本文的“设备”指的是 Android 系统将被安装的设备,例如某个型号的手机或平板)的也可能是针对主机(本文的“主机”指的是开发 Android 系统的机器,例如装有 Ubuntu 操作系统的 PC 机或装有 MacOS 的 iMac 或 Macbook)的。不同类型的模块的编译步骤和方法是不一样,为了能够一致且方便的执行各种类型模块的编译,在 config.mk 中定义了许多的常量,这其中的每个常量描述了一种类型模块的编译方式,这些常量有:

BUILD_HOST_STATIC_LIBRARY
BUILD_HOST_SHARED_LIBRARY
BUILD_STATIC_LIBRARY
BUILD_SHARED_LIBRARY
BUILD_EXECUTABLE
BUILD_HOST_EXECUTABLE
BUILD_PACKAGE
BUILD_PREBUILT
BUILD_MULTI_PREBUILT
BUILD_HOST_PREBUILT
BUILD_JAVA_LIBRARY
BUILD_STATIC_JAVA_LIBRARY
BUILD_HOST_JAVA_LIBRARY

通过名称大概就可以猜出每个变量所对应的模块类型。这些常量的值都是另外一个 Make 文件的路径,详细的编译方式都是在对应的 Make 文件中定义的。这些常量和 Make 文件的是一一对应的,对应规则也很简单:常量的名称是 Make 文件的文件名除去后缀全部改为大写然后加上“BUILD_”作为前缀。例如常量 BUILD_HOST_PREBUILT 的值对应的文件就是 host_prebuilt.mk。

Make目标说明

make /make droid

如果在源码树的根目录直接调用“make”命令而不指定任何目标,则会选择默认目标:“droid”(在 main.mk 中定义)。因此,这和执行“make droid”效果是一样的。

droid 目标将编译出整个系统的镜像。从源代码到编译出系统镜像,整个编译过程非常复杂。这个过程并不是在 droid 一个目标中定义的,而是 droid 目标会依赖许多其他的目标,这些目标的互相配合导致了整个系统的编译。

image

其他

Make目标说明
make clean执行清理,等同于:rm -rf out/。
make sdk编译Android SDK
make clean-sdk清理SDK编译产物
make update-api更新 API。在 framework API 改动之后,需要首先执行该命令来更新 API,公开的 API 记录在 frameworks/base/api 目录下。
make dist执行 Build,并将 MAKECMDGOALS 变量定义的输出文件拷贝到 /out/dist 目录。
make all编译所有内容,不管当前产品的定义中是否会包含。
make help帮助信息,显示主要的 make 目标。

Make目标说明

小结

Android 编译内容还有很多,更多详细内容应该多多参见源码。

参考

理解 Android Build 系统

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值