1.1 介绍
Android编译系统是基于GNU make,google设计它是为了提供编译性能和减少没必要重新编译的模块。而且相对makefile操作起来要容易多得。Android编译系统完成的并不仅仅是对目标(主机)系统二进制文件、java应用程序的编译、链接、打包等,而且还有包括生成各种依赖关系、确保某个模块的修改引起相依赖的文件的重新编译链接,甚至还包括目标文件系统的生成,配置文件的生成等,因此Android编译系统具有支持多架构(linux-x86、windows、arm等)、多语言(汇编、C、C++、Java等)、多目标、多编译方式。
Android编译系统源码目录是在build下,另外还有一些shell脚本,如此多文件的原因肯定是有的,如下:
1.Multiple Targets
2.Non-recuresive Make
3.Rapid Compile-Test Cycles
4.BothEnvironment and Config File Based Settings
这些原则可在build/core/build-system.html中可以找到。而且Android编译系统作为google一个项目一直在更新。
另外,理解编译系统也是我们移植系统的基础。
2 Android.mk
2.1 介绍
在Android编译系统中,他们编译文件都是用Android.mk。看下Android和一般的Makefile能编译的类型比较:
很明显,Android.mk的功能要比makefile更强大,这是根据Android整个系统有好多层从而来实现的功能。
2.2 语法规则
当然,Android.mk一样,都有自己的一套语法规则,下面说一些常用的变量。
一个Android.mk中可以生成多个可执行程序、动态或者静态库。模板如下:
LOCAL_SRC_FILES: 需要编译的文件
LOCAL_MODULE: 生成的文件名
LOCAL_C_INCLUDES:包含的头文件
LOCAL_STATIC_LIBRARIES: 要包含的静态文件
LOCAL_SHARED_LIBRARIES: 要包含的动态文件
include $(BUILD_EXECUTABLE):生成何种类型的文件,包括可执行程序、静态和动态库。
下面在看静态和动态库如何生成:
静态库生成:
动态库生成:
注意,在Android中不需要对C或C++源文件进行区分,统一加入LOCAL_C_FILES即可。
生成的目标文件放在以下目录:
前面我们讲了目标程序的编译方法,如下:
我们再看看主机程序的编译方法,如下:
我们也可以指定最后的目标安装路径,使用LOCAL_MODULE_PATH和LOCAL_UNSTRIPPED_PATH这两个宏,分别代表最终目标路径和未经符号分离的目标路径。
不同文件系统路径用下面宏选择:
然后我们再看例子:
当未指定LOCAL_MODULE_PATH时,默认宏为TARGET_ROOT。对于静态库,不会在目标文件系统中出现,也不存在指定目标路径的问题。