详解android.mk

前面在网上各种资料的帮助下,成功编译了ffmpeg、live555、openrtp等,本来以为已经基本掌握了android.mk的写法。这次在编译super Meye中一个小的自己写的c++文件,却出了大错。原因只在于我为了偷懒,直接复制了一个原来的android.mk文件,在上面就做了细微修改。可是,后来出现了各种各样的问题。最后发现,就是两个小的细节没有注意:1、工程名中有空格;2、.mk文件中多了一句LOCAL_C_INCLUDES := $(LOCAL_PATH) \

1、名中有空格?

    在我们新建一个工程命名时,名中有空格并不会报错。但是,当我们需要用到ndk编译时,则万万不可有空格。虽然ndk-r5版本后,ndk就集成了编译环境可以直接编译.cpp文件,但是其内部,其实还是借助了cygwin。cywin里的路径名中是不能有空格的,路径会直接在空格处截断。

   这是我的第一个问题,这个问题带来的直接后果就是,无论我怎么修改.cpp,.mk文件,它编译时出来的库都是错的,实际的东西好像都没有编译进去,使得我在java层调用native接口时,一直报UnsatisfiedLinkError。

2、.mk中多了一句LOCAL_C_INCLUDES

    导致的问题:无论我怎么修改,删除掉libs、obj,甚至卸载了这个apk,再下次编译时,还是直接加载了.so文件,并没有重新编译。

    这个原因需要从.mk文件每一条编译指令的作用说起。现附上成功编译的.mk文件

1 LOCAL_PATH := $(call my-dir)
2 include $(CLEAR_VARS)
3 LOCAL_MODULE := OWSP
4 LOCAL_SRC_FILES :=  OWSP.cpp nativeOWSP.cpp
5 LOCAL_LDLIBS := -lGLESv1_CM -llog -lz -ldl -lgcc
6 include $(BUILD_SHARED_LIBRARY)

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

.mk文件指令说明:

 1、LOCAL_PATH

     一个android.mk文件必须首先定义好LOCAL_PATH变量,用于在开发树中查找源文件。一般用法:LOCAL_PATH := $(call my-dir),其中,"my-dir”是由编译系统提供的宏函数,"call my-dir"用于返回当前路径,即这个.mk文件的目录。

2、include $(CLEAR_VARS)

    CLEAR_VARS指向一个编译脚本,几乎所有未定义的LOCAL_XXX变量都在"Module-description"中列出。必须在开始一个新模块前包含这句话:include $(CLEAR_VARS),用于重置除LOCAL_PATH变量外的所有LOCAL_XXX变量。

3、LOCAL_MODULE

    生成的模块名,这个变量必须定义,表示ndk-build后将要生成的库的名字。如:LOCAL_MODULE := OWSP,会生成libOWSP.so文件。

4、LOCAL_SRC_FILES

     本次编译需要打包进模块中的CC++源代码文件。注意:不必列出头文件和包含文件,编译系统会自动为我们找出依赖性的文件。文件之间可用“空格”或“TAB键”隔开,换行用“\”。

    如果是追加源代码文件的话,请用LOCAL_SRC_FILES +=
    注意:可以LOCAL_SRC_FILES := $(call all-subdir-java-files)这种形式来包含local_path目录下的所有java文件。

 

5、LOCAL_C_INCLUDES 

 

    本次编译需要的头文件,一个相对于当前目录可选的路径名单。比如:LOCAL_C_INCLUDES :=  $(LOCAL_PATH)/../ffmpeg-0.8.7  $(LOCAL_PATH)/../live555

6、LOCAL_SHARED_LIBRARIES

   表示模块在运行时要依赖的共享库(动态库),在链接时就需要,以便在生成文件时嵌入其相应的信息。

7、LOCAL_STATIC_LIBRARIES

     表示该模块需要使用哪些静态库,以便在编译时进行链接。

 

8、LOCAL_LDLIBS

    本次编译的链接选项,相当于gcc -l后的参数。

9、LOCAL_CFLAGS或LOCAL_CPPFLAGS

    也是编译的链接选项,相当于gcc -o后的参数。(注意:这种编译链接选项一般都放在后面写)

10、LOCAL_MODULE_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)
       至于LOCAL_MODULE_PATH 和LOCAL_UNSTRIPPED_PATH的区别,暂时还不清楚。

11、LOCAL_MODULE_TAGS

12、include $(BUILD_SHARED_LIBRARY)或STATIC...

     指向编译脚本,收集所有的你在LOCAL_XXX变量中提供的信息,并且决定如何把你列出的源代码文件编译成一个共享库。注意,你必须至少在包含这个文件之前定义LOCAL_MODULELOCAL_SRC_FILES

等等,还有许多其他的编译选项,就不一一列出了。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面是GNU Make ‘功能’宏,必须通过使用'$(call <function>)'来求值,他们返回文本化的信息。

my-dir

返回当前Android.mk所在的目录路径,相对于NDK编译系统的顶层。这是有用的,在Android.mk文件的开头如此定义:

LOCAL_PATH := $(call my-dir)

all-subdir-makefiles

   返回一个位于当前'my-dir'路径的子目录列表。例如,看下面的目录层次:

sources/foo/Android.mk

sources/foo/lib1/Android.mk

sources/foo/lib2/Android.mk

如果sources/foo/Android.mk包含一行

include $(call all-subdir-makefiles)

那么它就会自动包含sources/foo/lib1/Android.mk sources/foo/lib2/Android.mk

这项功能用于向编译系统提供深层次嵌套的代码目录层次。注意,在默认情况下,NDK将会只搜索在sources/*/Android.mk中的文件。

this-makefile

返回当前Makefile的路径(即这个函数调用的地方) 

parent-makefile

  返回调用树中父Makefile路径。即包含当前MakefileMakefile路径。 

grand-parent-makefile

 参考:http://www.cnblogs.com/leaven/archive/2011/01/25/1944688.html

         http://blog.sina.com.cn/s/blog_55465b4701017rap.html

         http://blog.sina.com.cn/s/blog_4ad7c2540101beo1.html这篇讲的非常详细。

posted @ 2013-06-03 11:25  little_star  阅读(575)  评论(0编辑  收藏  举报