1.编译过程
1) source build/envsetup.sh
2) lunch,选择编译的平台
3)make -j4
##2. 命令介绍
1)m 编译整个android工程
2)mm 编译当前目录下模块,不包括依赖项
3)mmm path 编译指定目录下的模块
4)mma 编译当前目录下所有模块,包括依赖项
5)mmma path 编译指定目录下所有模块,含依赖项
PS: mm/mmm编译较快,mma/mmma会把所有的依赖项一同编译,比较缓慢,首次编译时用mma,以后用mm编译。
3.Android.mk解析
1. mk文件
一个android子项目中会存在一个或多个Android.mk文件
1) 单一的Android.mk文件
直接参考NDK的sample目录下的hello-jni项目,在这个项目中只有一个Android.mk文件
2) 多个Android.mk文件
如果需要编译的模块比较多,我们可能会将对应的模块放置在相应的目录中, 这样,我们可以在每个目录中定义对应的Android.mk文件(类似于上面的写法), 最后,在根目录放置一个Android.mk文件,内容如下:
include $(call all-subdir-makefiles)
只需要这一行就可以了,它的作用就是包含所有子目录中的Android.mk文件
2. 变量
注意:‘:=’是赋值的意思;’+=’是追加的意思;‘$’表示引用某变量的值。
1)LOCAL_PATH: 这个变量用于给出当前文件的路径。
必须在 Android.mk 的开头定义,可以这样使用:
LOCAL_PATH := $(call my-dir)
如当前目录下有个文件夹名称 src,则可以这样写 $(call src),那么就会得到 src 目录的完整路径
这个变量不会被$(CLEAR_VARS)清除,因此每个 Android.mk 只需要定义一次(即使在一个文件中定义了几个模块的情况下)。
2)CLEAR_VARS: 必须在开始一个新模块之前包含这个脚本:include$(CLEAR_VARS),用于重置除LOCAL_PATH变量外的,所有LOCAL_XXX系列变量。
3)LOCAL_MODULE: 这是模块的名字,它必须是唯一的,而且不能包含空格。
4)LOCAL_SRC_FILES: 这是要编译的源代码文件列表。
只要列出要传递给编译器的文件,因为编译系统自动计算依赖。注意源代码文件名称都是相对于 LOCAL_PATH的,你可以使用路径部分,例如:
LOCAL_SRC_FILES := foo.c toto/bar.c\
Hello.c
文件之间可以用空格或Tab键进行分割,换行请用"\"
如果是追加源代码文件的话,请用LOCAL_SRC_FILES +=
5)LOCAL_STATIC_LIBRARIES: 表示该模块需要使用哪些静态库,以便在编译时进行链接时就需要
6)LOCAL_SHARED_LIBRARIES: 表示模块在运行时要依赖的共享库(动态库),在链接时就需要
7)LOCAL_LDLIBS: 编译模块时要使用的附加的链接器选项。这对于使用‘-l’前缀传递指定库的名字是有用的。
例如,LOCAL_LDLIBS := -lz表示告诉链接器生成的模块要在加载时刻链接到/system/lib/libz.so
可查看 docs/STABLE-APIS.TXT 获取使用 NDK发行版能链接到的开放的系统库列表。
8)LOCAL_MODULE_PATH 和 LOCAL_UNSTRIPPED_PATH
在 Android.mk 文件中, 还可以用LOCAL_MODULE_PATH 和LOCAL_UNSTRIPPED_PATH指定最后的目标安装路径.
不同的文件系统路径用以下的宏进行选择:
TARGET_ROOT_OUT:表示根文件系统。
TARGET_OUT:表示 system文件系统。
TARGET_OUT_DATA:表示 data文件系统。
用法如:LOCAL_MODULE_PATH :=$(TARGET_ROOT_OUT)
9)BUILD_STATIC_LIBRARY:编译为静态库。
BUILD_SHARED_LIBRARY :编译为动态库
BUILD_EXECUTABLE:编译为Native C可执行程序
4. 编译后的文件
经过make编译后的产物,都位于/out目录,该目录下主要关注下面几个目录:
1). /out/host:Android开发工具的产物,包含SDK各种工具,比如adb,dex2oat,aapt等。
2) /out/target/common:通用的一些编译产物,包含Java应用代码和Java库;
3) /out/target/product/[product_name]:针对特定设备的编译产物以及平台相关C/C++代码和二进制文件;
其中,有几个重量级的镜像文件:
system.img:挂载为根分区,主要包含Android OS的系统文件;
ramdisk.img:主要包含init.rc文件和配置文件等;
userdata.img:被挂载在/data,主要包含用户以及应用程序相关的数据;
当然还有boot.img,reocovery.img等镜像文件,这里就不介绍了。
##5. 编译遇到的问题
###1. GC overhead limit exceeded
解决:
1 | export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4g" |
2. lunch一定要在根目录
lunch一定要在根目录进行,否则会删除之前编译好的文件。
例如:我先全部编译一遍,此时在out目录下生成镜像文件。如果再新建一个Terminal,cd 到其它目录里,source一下,然后lunch,此时我原先编译好的文件都丢失了。
3. 编译完成后刷入镜像
make snod命令