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

来源:互联网 发布:看youtube软件 编辑:程序博客网 时间:2024/05/23 05:07


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

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

 

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

 

source build/envsetup.sh

 

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

 

名称说明croot切换到源码树的根目录m在源码树的根目录执行 makemmBuild 当前目录下的模块mmmBuild 指定目录下的模块cgrep在所有 C/C++ 文件上执行 grepjgrep在所有 Java 文件上执行 grepresgrep在所有 res/*.xml 文件上执行 grepgodir转到包含某个文件的目录路径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.imgmakerecoveryimage生成 recovery.imgmakeuserdataimage生成 userdata.imgmakecacheimage生成 cache.img
转自:http://www.cnblogs.com/cuan/p/4150036.html