下面这些变量用于对模块进行描述,这些变量应该在 include $(CLEAR_VARS) 和 include $(BUILD_XXXX) 之间定义好。 LOCAL_PATH (必须) 这个变量表示当前文件(一般是Android.mk)所在的路径, 该变量很重要,必须定义 (在Android.mk文件的开头处定义)。常
下面这些变量用于对模块进行描述,这些变量应该在 include $(CLEAR_VARS) 和 include $(BUILD_XXXX) 之间定义好。
LOCAL_PATH (必须)
这个变量表示当前文件(一般是Android.mk)所在的路径,该变量很重要,必须定义(在Android.mk文件的开头处定义)。常见写法如下:
LOCAL_PATH := $(call my-dir)
宏函数‘my-dir’, 由编译系统提供, 用于返回当前路径(即包含Android.mk file文件的目录)。(第7部分会详细介绍)
该变量不会被 include $(CLEAR_VARS) 清空,所以不论Android.mk定义了几个模块,一个Android.mk只需要在开头定义一次即可。
include $(CLEAR_VARS)
CLEAR_VARS是一个GNU
Make系统变量,指向一个编译脚本。该脚本功能为你清除许多
LOCAL_XXX 变量 ( 例如 LOCAL_MODULE , LOCAL_SRC_FILES ,LOCAL_STATIC_LIBRARIES,等等…),除 LOCAL_PATH外。
( android 安装目录下的/build/core/config.mk 文件看到其定义)
LOCAL_MODULE (必须)
该变量定义当前模块的名字,名字必须唯一,不能有空格。这个变量必须在 include $(BUILD_XXX) 之前定义好。默认情况下,这里的名字会用来得到输出文件的名字。例如模块名为foo,则得到的输出文件为libfoo.so。但是,如果你要在其他模块的Android.mk文件或Application.mk中引用这个模块,应该用foo这个模块名,而不要用libfoo.so这个文件名。
LOCAL_MODULE_FILENAME (可选)
该变量可以用来重定义输出文件的名字。默认情况下,foo模块得到的静态库的名字为 libfoo.a,动态库的名字为libfoo.so(UNIX规范)。当定义了LOCAL_MODULE_FILENAME之后,输出文件名就是这个变量指定的名字,例如:
[plain] view
plaincopy
LOCAL_MODULE := foo-version-1
LOCAL_MODULE_FILENAME := libfoo
注意: LOCAL_MODULE_FILENAME不支持文件路径(所以不能有斜杠),不要写扩展名(文件路径和文件扩展名是由编译工具自动加上的)
LOCAL_SRC_FILES (必须)
该变量用来指定该模块对应的源文件,只把需要传给编译器的源文件名加进LOCAL_SRC_FILES,编译系统会自动处理头文件依赖。这里的文件名都是以
LOCAL_PATH 作为当前目录的(即相对于LOCAL_PATH目录),例如:
LOCAL_SRC_FILES := foo.c \#如果要换行,用反斜杠
bar.c
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_SRC_FILES:= $(call all-java-files-under, src)
LOCAL_MODULE_TAGS
LOCAL_MODULE_TAGS :=user eng tests optional samples shell_ash shell_mksh
user: 指该模块只在user版本下才编译
eng: 指该模块只在eng版本下才编译
tests: 指该模块只在tests版本下才编译
optional:指该模块在所有版本下都编译
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) 编译打包后,指定模块最后的目标存放路径
TARGET_ROOT_OUT:表示根文件系统。
TARGET_OUT:表示system文件系统。
TARGET_OUT_DATA:表示data文件系统。
LOCAL_CPP_EXTENSION (可选)
用来定义C++代码文件的扩展名。必须以句点开头(即 “.”),默认值是“.cpp”,可以修改,例如:
LOCAL_CPP_EXTENSION := .cxx
从 NDK r7 这个版本开始,该变量可以支持多个扩展名了,例如:
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
LOCAL_CPP_FEATURES (可选)
该变量用来指定C++代码所依赖的特殊C++特性。例如,如果要告诉编译器你的C++代码使用了RTTI(RunTime Type Information):
LOCAL_CPP_FEATURES := rtti
如果要指定你的C++代码使用了C++异常,则:
LOCAL_CPP_FEATURES := exceptions
该变量可以同时指定多个特性。例如: LOCAL_CPP_FEATURES := rtti features
这个变量的作用就是在编译模块的时候,开启相应的编译器/链接器标志。对于预编译的文件,该变量表明该预编译的库依赖了这些特性,从而确保最后的链接工作正确进行。与该变量等价的做法是在LOCAL_CPPFLAGS中写上
-frtti -fexceptions 等标志选项。但是,推荐用这里的方法。
LOCAL_C_INCLUDES
加入需要的头文件搜索路径
一个路径的列表,是NDK根目录的相对路径(LOCAL_SRC_FILES中的文件相对于LOCAL_PATH)。当编译C/C++、汇编文件时,这些路径将被追加到头文件搜索路径列表中。例如:
LOCAL_C_INCLUDES := sources/foo
或者, LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo
这里的搜索路径会放在LOCAL_CFLAGS/LOCAL_CPPFALGS等标志的前面。 当使用ndk-gdb的时候,LOCAL_C_INCLUDES中的路径也会被用到。
LOCAL_CFLAGS
指定当编译C/C++源码的时候,传给编译器的标志。它一般用来指定其他的编译选项和宏定义。
注意:尽量不要在Android.mk中修改优化/调试等级,因为在Application.mk中定义了相关信息之后编译系统会自动处理这些问题。
LOCAL_CXXFLAGS (废除, LOCAL_CPPFLAGS的别名)
LOCAL_CPPFLAGS (可选)
编译C++代码的时候传递给编译器的选项(编译C代码不会用这里的选项)。最后得到的命令行选项中,这里指定的选项在 LOCAL_CFLAGS 指定的选项的后面。
LOCAL_STATIC_LIBRARIES
指定应该链接到当前模块的静态库(可指定多个)。当前模块是动态库时,该选项才有意义。
LOCAL_SHARED_LIBRARIES
指定的是运行时该模块所依赖共享库(可指定多个)。这些信息是链接阶段必须的。
LOCAL_WHOLE_STATIC_LIBRARIES
它是LOCAL_STATIC_LIBRARIES的变体,用来表示它对应的模块对于linker来说应该是一个“whole archive”(见GNU linker 文档,关于 --whole-archive的资料)。当静态库之间有循环依赖时,会用到这个选项。注意,当编译动态库时,这个选项会强行把所有的对象文件组装到一起;不过,在编译可执行文件的时候情况不是这样的。
LOCAL_LDLIBS
用来指定模块编译时的其余连接器标志。例如:
LOCAL_LDLIBS := -lz
告诉链接器在加载该共享库的时候必须链接 /system/lib/libz.so 这个共享库。
如果想知道Android系统中有哪些共享库可以链接,参考 Stable APIs。
LOCAL_ALLOW_UNDEFINED_SYMBOLS
默认情况下,当编译一个共享库的时候,遇到未定义符号引用就会报告一个“undefined symbol”错误。这有助于修复你的代码中存在的bug。
如果因为某种原因,必须禁止该检测,可以把这个变量设置为true。注意,编译出的共享库有可能在加载的时候就报错导致程序退出。
LOCAL_ARM_MODE
LOCAL_ARM_NEON
LOCAL_DISABLE_NO_EXECUTE
Android NDK r4增加了对“NX bit“安全特性的支持。它是默认开启的,如果你确定自己不需要该特性,你可以将它关闭,即:
LOCAL_DISABLE_NO_EXECUTE := true
该变量不会修改ABI,只会在 ARMv6以上的CPU的内核上启用。开启该特性编译出的代码无需修改可运行在老的CPU上(也就是说所有ARM的CPU都能运行)。
参考信息:
http://en.wikipedia.org/wiki/NX_bit
http://www.gentoo.org/proj/en/hardened/gnu-stack.xml
LOCAL_EXPORT_CFLAGS
这个变量定义一些C/C++编译器flags。这些flags(标志)会被追加到使用了这个模块(利用LOCAL_STATIC_LIBRARIES和LOCAL_SHARED_LIBRARIES)的模块的LOCAL_CFLAGS 定义中去。
假如foo模块的声明如下:
[plain] view
plaincopy
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_CFLAGS := -DFOO=1
include $(BUILD_STATIC_LIBRARY)
bar模块依赖foo模块,声明如下:
[plain] view
plaincopy
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_CFLAGS := -DBAR=2
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
因此在编译bar模块的时候,它的编译器标志就是 “-DFOO=1 -DBAR=2”。 导出的flags 加上本模块的 LOCAL_CFLAGS,成为最后传给编译器的flags。这样修改起来就很容易。这种依赖关系是可传递的,例如,如果zoo依赖bar,bar依赖foo,那么zoo就会同时有bar和foo的导出flags。
注意,编译模块自身时,不会使用它所导出的flags。例如在编译上面的foo模块时, -DFOO=1 不会传递给编译器。
LOCAL_EXPORT_CPPFLAGS
与 LOCAL_EXPORT_CFLAGS 相同,是跟C++相关的标志。
LOCAL_EXPORT_C_INCLUDES
与 LOCAL_EXPORT_CFLAGS 相同,但是只用于头文件搜索路径。当你的共享库有多个模块,而且互相之间有头文件依赖时有用。用法详见 Import Module。
LOCAL_EXPORT_LDLIBS
与 LOCAL_EXPORT_CFLAGS 相同,但是只用于连接器的flag。注意这里被导人的链接器标志将追加到模块的 LOCAL_LDLIBS。
例如当foo模块是一个静态库并且代码依赖于系统库时,该变量非常有用。 LOCAL_EXPORT_LDLIBS 可以用于导出该依赖:
[plain] view
plaincopy
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
此处在编译bar模块的时候,它的链接器标志将加上一个 -llog,表示它依赖于系统提供的 liblog.so,因为它依赖 foo 模块。
LOCAL_FILTER_ASM
这个变量指定一个shell命令,用于过滤LOCAL_SRC_FILES 中列出的汇编文件或者LOCAL_SRC_FILES列出的文件所编译出的汇编文件。定义该变量后,将导致以下行为:
1)所有的C/C++源码首先翻译为临时汇编文件(如果不定义LOCAL_FILTER_ASM,则C/C++源码直接编译为 obj 文件)
2)这些汇编文件被传给 LOCAL_FILTER_ASM 所指定的shell命令处理,得到一批新的汇编文件。
3)这些新的汇编文件再被编译成obj文件。
换句话说,如果你定义:
[plain] view
plaincopy
LOCAL_SRC_FILES := foo.c bar.S
LOCAL_FILTER_ASM := myasmfilter
则foo.c首先传给编译器(gcc),得到 foo.S.orignal,然后这个 foo.S.original 被传给你指定的过滤器(LOCAL_ASM_FILTER),得到 foo.S,然后再传给汇编器(例如as),得到 foo.o。 bar.S 直接传给过滤器得到 bar.S.new,然后再传给汇编器,得到
bar.o。即在从*.S到*.o的编译流程中增加了一个过滤的环节。
过滤器必须是独立的shell命令,输入文件作为它的第一个命令行参数,输出文件作为第二个命令行参数,例如:
[plain] view
plaincopy
myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S
myasmfilter bar.S $OBJS_DIR/bar.S