Android.mk是Android提供的一种makefile文件,用来指定诸如编译生成so库名、引用的头文件目录、需要编译的.c/.cpp文件和.a静态库文件等。要掌握jni,就必须熟练掌握Android.mk的语法规范。
由于该文件会被NDK的编译工具解析多次,因此应该尽量减少源码中声明变量,因为这些变量可能会被多次定义从而影响到后面的解析。这个文件的语法允许把源代码组织成模块,每个模块属于下列类型之一:
- APK程序:一般的Android程序,编译打包生成apk文件。
- JAVA库:java类库,编译打包生成jar包文件。
- C\C++应用程序:可执行的C/C++应用程序。
- C\C++静态库:编译生产C/C++静态库,并打包成.a文件。
- C\C++共享库:编译生成共享库(动态库),并打包成.so文件,有且只有共享库才能被安装/复制到APK包中。
一个android子项目中会存在一个或多个Android.mk文件
- 单一的Android.mk文件:直接参考NDK的sample目录下的hello-jni项目,在这个项目中只有一个Android.mk文件
- 多个Android.mk文件:如果需要编译的模块比较多,我们可能会将对应的模块放置在相应的目录中,这样,我们可以在每个目录中定义对应的Android.mk文件(类似于上面的写法), 最后,在根目录放置一个Android.mk文件,内容如下: include $(call all-subdir-makefiles) 只需要这一行就可以了,它的作用就是包含所有子目录中的Android.mk文件
- 多个模块共用一个Android.mk :这个文件允许你将源文件组织成模块,这个模块中含有:静态库(.a文件) 和动态库(.so文件) 只有共享库才能被安装/复制到您的应用软件(APK)包中 include $(BUILD_STATIC_LIBRARY)编译出的是静态库 ;include $(BUILD_SHARED_LIBRARY)编译出的是动态库
这里参考了网上一个通用的例子,编译简单的“Hello World”,来说明一下Android.mk编写。例如下面的文件:
sources/test/hello.c
sources/test/Android.mk
其中“hello.c”是一个JNI共享库,实现返回“hello world”字符串的原生方法。因此,Android.mk文件内容如下:
LOCAL_PATH := $(call my-