最近在开发与修改过程中一直是按着别人写好的文档去操作的,配置开发环境与编译及部署应用都是知道怎么去做,而不知道背后执行的过程是什么,尤其是原生android源码还有MTK源码及各大公司自己制定的源码都有很多不一样的地方,当我们已经习惯敲几个命令去执行编译的时候,可能很少会去思考它背后的原理。当然,这本身并没有什么问题,因为说到底这些编译脚本和命令,只是一堆工具。而对我们目前工作真正有帮助的是熟练掌握这些工具的使用,而不是去了解它的原理。如果我们只是做纯粹的应用软件,上述观点已经足够。但是如果我们做系统级的开发,针对整个系统进行移植和开发,了解些Android的编译系统方面的知识,还是很有帮助的。一下是自己通过看书和查找相关资料得到的一些学习心得,通过博客以后方便自己查看。
一.Android系统概览
1. Android 源码结构
Android框架那张图片我以前看了很多遍,一直没理解,最近深入学习才慢慢理解一点点,这里就贴图了,由于在公司电脑上有源码,自己电脑没有,图片来自网上整体差不多,先看看android执行的流程.
.Android源码编译流程关于编译android源码环境配置过程我就不说了,网上一堆,一开始我自己配了两天,现在只要几个小时就可以了(熟悉了就好)。
源码下载好,如第一张图,进入命令行在工程根目录下执行make命令 (对于原生的来说,对于第三方公司不一样)。在源码下有一个Makefile文件,执行make命令,等同于执行make Makefile 命令。Makefile文件的内容:
### DO NOT EDIT THIS FILE ###
include build/core/main.mk
### DO NOT EDIT THIS FILE ###
所有的流程控制都在mian.mk文件中,所以mian.mk是编译的开始文件。
在build/core/main.mk里主要完成以下内容:
1.初始化相关参数设置(buildspec.mk、envsetup.mk、config.mk)
2.检测编译环境和目标环境是否符合要求
3.决定目标product名称
4.读取product的配置信息及目标平台信息
5.清除输出目录
6.检查相关编译工具版本号
7.读取Board的配置
8.读取所有Module的配置
9.根据配置产生必要的规则(build/core/Makefile)
10.生成image镜像
Main.mk文件按照下面的次序包含个mk文件(建议简单看一下文件中的内容)
1. config.mk
2. cleanbuild.mk
3. version_checked.mk
4. definitions.mk
config.mk文件按照下面的次序包含各个mk文件
1. buildspec.mk
2. envsetup.mk
3. vendor/qcom-proprietary/common/build/define.mk
4. boardconfig.mk
boardconfig.mk会在两个目录中寻找
1. build/target/$targetdevice/boardconfig.mk
2. vender/*/$ targetdevice/boardconfig.mk
envsetup.mk中包含下面的mk文件
1. version_default.mk
下图简要介绍了Android build system的配置部分的主要构成及相互关系。
在build/core/main.mk文件中,简单设置了几个环境变量后,就引入了config.mk文件。
include $(BUILD_SYSTEM)/config.mk该文件定义一些编译模块的生成规则,每一个本地
模块最后都会include其中的一种来生成目标模块。命令变量其实是对应的mk文件名,所有的Android.mk文件里基本上都包含上述命令变量,如:CLEAR_VARS:用来清除之前定义的环境变量,BUILD_SHARED_LIBRARY:用来指定编译动态库过程。
config.mk下面几个重要的编译命令:
通过依次查找mk文件,执行其中编译命令进行了整个源码的编译,编译完成之后会在源码目录下生成一个out目录(自己笔记本无法上图,后面会有的)。
后面会继续记录各个mk文件的内容及含义,以及 Android.mk的理解.
手写博客内容真痛苦,最后上一个out目录结构。
Android 编译完成后,将在根目录中生成一个out 文件夹,所有生成的内容均放置在这个文件夹中。out 文件夹如下所示:
out/
|-- CaseCheck.txt
|-- casecheck.txt
|-- host
| |-- common
| `-- linux-x86
`-- target
|-- common
`-- product
主要的两个目录为host 和target,前者表示在主机(x86)生成的工具,后者表示目标机(模认
为ARMv5)运行的内容。
host 目录的结构如下所示:
out/host/
|-- common
| `-- obj (JAVA 库)
`-- linux-x86
|-- bin (二进制程序)
|-- framework (JAVA 库,*.jar 文件)
|-- lib (共享库*.so)
`-- obj (中间生成的目标文件)
host 目录是一些在主机上用的工具,有一些是二进制程序,有一些是JAVA 的程序。
target 目录的结构如下所示:
out/target/
|-- common
| |-- R (资源文件)
| |-- docs
| `-- obj (目标文件)
`-- product
`-- generic
其中common 目录表示通用的内容,product 中则是针对产品的内容。
在common 目录的obj 中,包含两个重要的目录:
APPS 中包含了JAVA 应用程序生成的目标,每个应用程序对应其中一个子目录,将结合每个应
用程序的原始文件生成Android 应用程序的APK 包。
JAVA_LIBRARIES 中包含了JAVA 的库,每个库对应其中一个子目录。
在默认的情况下,Android 编译将生成generic 目录,如果选定产品还可以生成其他的目录。
generic 包含了以下内容:
out/target/product/generic/
|-- android-info.txt
|-- clean_steps.mk
|-- data
|-- obj
|-- ramdisk.img
|-- root
|-- symbols
|-- system
|-- system.img
|-- userdata-qemu.img
`-- userdata.img
在generic/obj/APPS 目录中包含了各种JAVA 应用,与common/APPS 相对应,但是已经打成
了APK 包。
system 目录是主要的文件系统,data 目录是存放数据的文件系统。
obj/SHARED_LIBRARIES 中存放所有动态库。
obj/STATIC_LIBRARIES 中存放所有静态库。
几个以img 为结尾的文件是几个目标映像文件,其中ramdisk 是作为内存盘的根文件系统映像,
system.img 是主要文件系统的映像,这是一个比较大的文件,data.img 是数据内容映像。这几个
image 文件是运行时真正需要的文件。
本文转自 646676684 51CTO博客,原文链接:http://blog.51cto.com/2402766/1076503,如需转载请自行联系原作者