首页 > 代码库 > Android.mk语法解析

Android.mk语法解析

Android.mk文件相当于是从Makefile文件中截取的小片段,非常非常的小!可被系统解析一次或者多次!应该尽量少的声明

该文件的一个很重要的组成部分就是模块


1.    - a static library   静态库

2.    - a shared library   动态库


只需要将动态库安装/拷贝到你的应用程序包即可,静态库是用来生成动态库的


你可以定义一个或多个模块,而且同一source file你可以放到多个模块中


编译之前还有一些细节要注意,比如:不需要将头文件或者一些依赖关系写到Android.mk文件中,NDK会自动给你计算出来的,这就意味这当你的NDK更新了,你也不用担心去修改Android.mk文件了


在详细描述语法之前,来先看一个小例子:

apps/hello-jni/project


在这个工程文件中:

-src文件夹包含了Java源码

-jni文件夹包含了本地源码,比如:jni/hello-jni.c


这个代码实现通过本地调用方法让vm返回去一个字符串生成的共享库


-jni/Android.mk文件,一般内容包含如下:

   LOCAL_PATH := $(call my-dir)


   include $(CLEAR_VARS)


   LOCAL_MODULE    := hello-jni

   LOCAL_SRC_FILES := hello-jni.c


   include $(BUILD_SHARED_LIBRARY)


每一个Android.mk文件都必须以LOCAL_PATH变量为开头,call  <function> 这个function的内容用的最多的是my-dir,但是还有其他的也可以用,代表的意思你可以去细看,比如all-subdir-makefiles,this-makefile,parent-makefile,grand-parent-makefile,import-module。通过它在development 结构代码中找到你的源文件,在例子当中的宏 函数‘my-dir‘是由编译系统提供的,用来返回当前文件夹的路径,这个路径里包含Android.mk文件


include $(CLEAR_VARS)

这一句也是必须要有的,通过CLEAR_VARS变量来清理除了LOCAL_PATH的整个系统的LOCAL_XXX全局变量的定义,比如OCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, etc...,这样操作完了之后,你就可以在下面进行数据的重新赋值了,担任这个变量也是有编译系统提供的


   LOCAL_MODULE    := hello-jni

这个是指定你本次要编译生成的动态链接库的文件夹名,必须是独一无二,名字中不能有空格,系统会自动给你添加前缀和后缀的,你现在的名字是hello-jni那么等编译完成之后,生成的文件名是libhello-jni.so


注意:如果你的LOCAL_MODULE    := libhello-jni,那么系统将不会给你添加前缀了


  LOCAL_SRC_FILES := hello-jni.c

LOCAL_SRC_FILES这个变量必须包含一系列的C/C++源文件来编译和组装到你的模块中,你不需要include你的头文件到这里,因为编译系统会自动计算你的依赖关系,你只需要列出直接编译的需要的文件即可。

默认的C++文件的后缀名是.cpp,如果你想更换的话可以通过LOCAL_CPP_EXTENSION=.c++ 变量来修改,千万不要忘了加‘.‘

还有这个变量下对应的文件或者路径都是相对于你的LOCAL_PATH 来说的,不要写错了


include $(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY变量是有编译系统提供的,指向一个GNU的makefile 脚本,用来收集最近一次修改的全局变量的值,确定建立什么,如何精确的执行,使用这个变量,那么你的Android.mk文件必不可少的的要有LOCAL_MODULE和LOCAL_SRC_FILES的定义。生成的库文件规则:lib$(LOCAL_MODULE).so。


编译静态库(BUILD_STATIC_LIBRARY )和上面大同小异,必不可少的的要包含 LOCAL_STATIC_LIBRARIES 和 LOCAL_WHOLE_STATIC_LIBRARIES 的定义。生成库文件的规则是:lib$(LOCAL_MODULE).a


PREBUILT_SHARED_LIBRARY

PREBUILT_STATIC_LIBRARY

预编译共享库和静态库使用方法和都是上面的一样,在Android.mk文件的最后添加一个include $();

不同的地方就是这个Android.mk文件不会生成新的库,而是将你的预编译库拷贝到$PROJECT/obj/local,剥离处理过的拷贝到$PROJECT/libs/<abi>


特别需要注意的地方是,此时你的LOCAL_SRC_FILES 存放的是你的共享库的路径PATH,不在是某个C/C++文件了,同时如果你的共享库还依赖的*.h文件,你还需要通过LOCAL_EXPORT_C_INCLUDES 将文件导过来


TARGET_ARCH

这个设定你的cpu结构是arm  x86


TARGET_PLATFORM

网上查看到的值为:generic 这个就是指定你要编译的目标机平台名称,比如:

android-3      -> Official Android 1.5 system images

    android-4      -> Official Android 1.6 system images

    android-5      -> Official Android 2.0 system images

    android-6      -> Official Android 2.0.1 system images

    android-7      -> Official Android 2.1 system images

    android-8      -> Official Android 2.2 system images

    android-9      -> Official Android 2.3 system images

    android-14     -> Official Android 4.0 system images


TARGET_ARCH_ABI    这个abi是Application Binary Interface的简称

  这个变量的值是有CPU+abi组合而成的

  目前支持两种:armeabi   针对的是armv5te指令集 通用性比较强,但是效率要比下面的低

                armeabi-v7a   针对的是armv7-a指令集

  针对以上两者的区别可以参考:http://www.myexception.cn/android/1594360.html


LOCAL_MODULE_FILENAME

  LOCAL_MODULE生成的库文件会自动添加前缀和后缀,但是如果你使用LOCAL_MODULE_FILENAME,那么将会改变之前生成的库文件的名称

  注意:该变量的值不能是路径同时名称不能添加后缀名,编译系统会自动为你添加


LOCAL_CPP_EXTENSION

  该变量是可选的,当你的C++文件的后缀名不是cpp的时候,你可以使用该变量来指定你的编译系统识别c++后缀的名称

  在NDK r7版本之后,该变量可以这么写:LOCAL_CPP_EXTENSION := .cxx .cpp .cc


LOCAL_C_INCLUDES

  编译的时候将你要追加的路径添加到此,而且必须放在 LOCAL_CFLAGS / LOCAL_CPPFLAGS 之前,最好是使用LOCAL_C_INCLUDES来代替LOCAL_CFLAGS / LOCAL_CPPFLAGS


LOCAL_LDLIBS

  这个是用来加载一些特定的系统库,比如经常用的liblog.so。使用的时候必须添加一个“-l”的前缀

  目前遇到的有:

  -lz   -ldl    -lGLESv1_CM     -lGLESv2      -ljnigraphics     -lOpenSLES      -lOpenMAXAL



参考:

http://www.kandroid.org/ndk/docs/ANDROID-MK.html

http://www.cnblogs.com/wainiwann/p/3837936.html