您的位置:首页 > 移动开发 > Android开发

android编译流程简要分析与使用

2014-12-07 22:29 267 查看

android系统编译流程简要分析与使用

开发Linux编程的程序员都清楚,Makefile是一个很重要的文件,该文件一个重要作用就是指定了编译规则。如此庞大的android系统源码当然也不例外了。

android源码中Android.mk就充当了Makefile的角色。android系统的编译系统太过复杂了,没办法,那些可都是谷歌里面的大牛们写的,对于我等程序员来说,首先最重要的就是会用啊,老板不关心你知识渊博与否,就关心你能不能搞定问题,至于如何搞定老板不关心。所以这里我只是简单的介绍下android的编译系统,目的很简单,如果要添加一个新平台的话,知道看哪些文件,修改哪些文件就可以了。

下图所示编译android系统的三大步骤。



source build/envsetup.sh


上面的命令引入了
build/envsetup.sh
脚本。该脚本的作用是初始化编译环境,并引入一些辅助的 Shell 函数,这其中就包括第二步中选择目标所用的lunch 函数。除此之外,该文件中还定义了其他一些常用的函数,如下所示:

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


第二步是调用 lunch 函数,并指定参数为“full-eng”。lunch 函数的参数用来指定此次编译的目标设备以及编译类型。在这里,这两个值分别是“full”和“eng”。“full”是 Android 源码中已经定义好的一种产品,是为模拟器而设置的。而编译类型会影响最终系统中包含的模块,下图所示是三种编译类型,前面的文章只是稍微提了一下:

名称说明
eng默认类型,该编译类型适用于开发阶段。
当选择这种类型时,编译结果将:

安装包含 eng, debug, user,development 标签的模块

安装所有没有标签的非 APK 模块

安装所有产品定义文件中指定的 APK 模块

user该编译类型适合用于最终发布阶段。
当选择这种类型时,编译结果将:

安装所有带有 user 标签的模块

安装所有没有标签的非 APK 模块

安装所有产品定义文件中指定的 APK 模块,APK 模块的标签将被忽略

userdebug该编译类型适合用于 debug 阶段。
该类型和 user 一样,除了:

会安装包含 debug 标签的模块

编译出的系统具有 root 访问权限

第三步执行命令

make -j2


才真正开始执行编译。make 的参数“-j”指定了同时编译的 Job 数量,这是个整数,该值通常是编译主机 CPU 支持的并发线程总数的 1 倍或 2 倍(例如:在一个 4 核,每个核支持两个线程的 CPU 上,可以使用 make -j8 或 make -j16,当然也要考虑机器的内存大小!!!)。

编译结果目录

所有的编译产物都将位于 /out 目录下,该目录下主要有以下几个子目录:

/out/host/:该目录下包含了针对主机的 Android 开发工具的产物。即 SDK 中的各种工具,例如:emulator,adb,aapt 等。

/out/target/common/:该目录下包含了针对设备的共通的编译产物,主要是 Java 应用代码和 Java 库。

/out/target/product/<product_name>/:包含了针对特定设备的编译结果以及平台相关的 C/C++ 库和二进制文件。其中,<product_name>是具体目标设备的名称。

前面我们编译的是模拟器版本的android系统,他的产品名称是generc.

首先在android源码的根目录下有一个makefile文件,如下图所示,可知其指向了build/core/中的main.mk。

好了,我们已经非常简单的介绍了一下android编译的三个步骤,现在我们考虑一个问题,大家都知道android是开源的操作系统,各个手机厂商都可以使用。android系统源码,大家也看到了,非常的庞大与复杂。好在谷歌工程师早就想好了对策,所有android编译都是模块化的,按照谷歌官方推荐的规则去添加自己的产品即可。

接下来我直接告诉大家添加一个新设备需要的几个重要的文件

vendorsetup.sh AndroidProduct.mk 产品定义文件 BoardConfig.mk

在说这几个文件的作用前,先以源码中自带的产品为例,宏观上介绍一下。谷歌公司推荐公司把自己的产品都添加到android源码目录中的device 文件夹中。

如下图所示是device文件夹中的内容,可以看到里面大多数是以公司名为名字的文件夹,比如飞思卡尔,三星,TI等。这个也很容易想嘛,就拿三星公司来说,人家旗下的android设备远远不止一种啊,

所以为了方便起见,device目录下都是公司名字,公司文件夹下存放的是该公司的具体产品设备。





以samsung公司的toro产品为例,说一下如何将这个产品添加到android系统源码中去的。

首先要做的肯定是要在执行lunch命令后,出现的产品列表中显示这个产品吧。。。



vendorsetup.sh 这个文件就是干这个事情的,那么他在哪里呢???肯定是在产品的目录里面了。由下图可以看出来,该文件在产品的根目录下,其内容也就是一行代码而已。add_lunch_combo是一个函数,当执行完source build/envsetup.sh后,该函数就可用了,他的作用就是添加一个产品到lunch显示列表中去,full_toro-userdebug格式为“产品名称+编译类型”。



光是这样还不够啊。以三星手机为例,同一款手机人家还分韩版,欧版,港版,大陆版。。。所以你要告诉android编译系统,你编译的是哪一个吧。

AndroidProduct.mk文件顾名思义啊,就是干这个事情的。该文文件中的内容很简单,其中只需要定义一个变量,名称为“PRODUCT_MAKEFILES”,该变量的值为产品版本定义文件名的列表,例如:

PRODUCT_MAKEFILES :=  $(LOCAL_DIR)/full_toro.mk


从中可以看出上述命令中的full_toro.mk才是产品真正的定义文件呢,其内容如下,可以看出该文件中定义了产品的名称,设备名称等,还指定了一些文件的拷贝路径。



PRODUCT_NAME:表示产品名字,它要和最终出现的编译项产品名一致。

PRODUCT_DEVICE:表示设备名字,它要和将来创建的设备目录名字一致。

BoardConfig.mk文件用来配置设备的硬件信息,例如:该设备的CPU架构,Wifi 相关信息,还有 bootloader,内核,大小位置等信息。

好,到这里我们已经知道如何添加一个新的产品到android系统中了。

下面列出了,在android目录中执行make 命令时,后面可以跟哪些目标。

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 snod从已经编译出的包快速重建系统镜像。
make libandroid_runtime编译所有 JNI framework 内容。
makeframework编译所有 Java framework 内容。
makeservices编译系统服务和相关内容。
make <local_target>编译一个指定的模块,local_target 为模块的名称。
make clean-<local_target>清理一个指定模块的编译结果。
makedump-products显示所有产品的编译配置信息,例如:产品名,产品支持的地区语言,产品中会包含的模块等信息。
makePRODUCT-xxx-yyy编译某个指定的产品。
makebootimage生成 boot.img
makerecoveryimage生成 recovery.img
makeuserdataimage生成 userdata.img
makecacheimage生成 cache.img
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐