原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处 、作者信息和本声明。否则将追究法律责任。
http://ikinglai.blog.51cto.com/6220785/1215819
- a static library 静态库
LOCAL_PATH := $(call my-dir)
... declare one module
LOCAL_PATH := $(call my-dir)
... declare another module
# extra includes at the end of the Android.mk
include $(LOCAL_PATH)/foo/Android.mk
MY_LOCAL_PATH := $(call my-dir)
LOCAL_PATH := $(MY_LOCAL_PATH)
... declare one module
include $(LOCAL_PATH)/foo/Android.mk
LOCAL_PATH := $(MY_LOCAL_PATH)
... declare another module
all-subdir-makefiles
sources/foo/Android.mk
sources/foo/lib1/Android.mk
sources/foo/lib2/Android.mk
include $(call all-subdir-makefiles)
那么它会自动的包含sources/foo/lib1/Android.mk 和 sources/foo/lib2/Android.mk。
这个函数主要用来为编译系统提供更深层次的源代码目录结构。注意默认情况下,NDK仅仅查找sources/*/Android.mk中的文件。
parent-makefile
grand-parent-makefile
$(call import-module, <name>)
它会在NDK_MODULE_PATH环境变量引用的目录列表中,查找所有标记为<name>的mudule,并自动为你包含它的Android.mk文件。
Module-description变量:
----------------------------------
下面的这些变量,用来描述编译系统中的module。你必须在'include $(CLEAR_VARS)' 和 'include $(BUILD_XXXXX)'之间来定义一些变量。根据前面的描述,$(CLEAR_VARS)会清除所有这些变量的定义,除非在它们的描述中显示的指出来。
你可以通过LOCAL_MODULE_FILENAME覆盖这个默认值(see below)。
LOCAL_MODULE_FILENAME
这个变量是可选的,允许你重新定义生成文件的名称。默认,module <foo>总是生成lib<foo>.a的静态库或者lib<foo>.so的动态库,这些都是Unix的约定。
你可以用LOCAL_MODULE_FILENAME覆盖掉这个默认值,例如:
LOCAL_MODULE := foo-version-1
LOCAL_MODULE_FILENAME := libfoo
注意:在你的LOCAL_MODULE_FILENAME不需要添加路径或者文件后缀,这些编译系统会自动帮你处理好。
LOCAL_SRC_FILES
这个是编译module的源文件列表。只有在这些列表中的源文件才能传递给编译器,编译系统会自动为你计算依赖关系。
注意这些源文件都是相对于LOCAL_PATH,你可以使用path components,如:
LOCAL_SRC_FILES := foo.c \
toto/bar.c
注意:在编译文件中,总是要用Unix风格的正斜杠(/),而不要使用windows风格的反斜杠。
LOCAL_CPP_EXTCEPTION
这是一个可选的变量,用来定义C++源文件的后缀。必须要以一个点开头,默认的是‘.cpp’,但是你可以修改它。如:
LOCAL_CPP_EXTCEPTION := .cxx
从NDK r7开始,你可以在这个变量中定义一序列的后缀,如:
LOCAL_CPP_EXTCEPTION := .cxx .cpp .cc
LOCAL_CPP_FEATURES
这是一个可选的变量,可以让你的代码使用一些c++的特性。为了让你的代码使用RTTI(RunTime Type Information),可以使用:
LOCAL_CPP_FEATURES := rtti
为了让你的代码支持c++异常,可以使用:
LOCAL_CPP_FEATURES := exceptions
你可以同时使用它们(顺序不重要)
LOCAL_CPP_FEATURES := rtti features
这个变量的作用是,当从源代码编译module的时候,可以启用正确的compiler/linker标志。对于预编译二进制文件,这同样有助于声明二进制文件所依赖的特性,从而确保最终的链接器能正确工作。
建议你使用这个变量,代替在LOCAL_CPPFLAGS中直接定义-frtti、-fexceptions这种用法。
LOCAL_C_INCLUDES
相对于NDK根目录的一个可选路径列表,当编译所有源代码时(c,c++或者两者的组合),将会添加到包含搜索路径中。如:
LOCAL_C_INCLUDES := sources/foo
或者甚至:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo
这些要放在LOCAL_CFLAGS / LOCAL_CPPFLAGS中对应包含的flag的前面。
当用ndk-gdb启动本地调试的时候,LOCAL_C_INCLUDES 同样会自动使用。
LOCAL_CFLAGS
当编译c和c++源代码的时候,传递给编译器的可选的标志集合。
对于指定附加宏的定义或者编译选项,是非常有帮助的。
重要:在Android.mk中不要试图改变optimization/debugging的级别,通过在Application.mk中指定合适的信息,系统会帮你自动处理,而且在debug过程中,NDK会生成有用的数据文件。
注意:在android-ndk-1.5_r1中,相应的标志只能应用在c文件上,不能用在c++上。这个问题已经被修正,从而匹配整个Android编译系统的行为。(你可以使用LOCAL_CPPFLAGS为c++源文件指定标志)
你可以通过LOCAL_CFLAGS += -I<path>来指定额外的包含路径,但是,对于这个使用LOCAL_C_INCLUDES会更好,因为这些路径可能在用ndk-gdb本地调试的时候会被用到。
LOCAL_CXXFLAGS
LOCAL_CPPFLAGS的别名。注意在后面的版本中,这个标志可能会被移除掉。
LOCAL_CPPFLAGS
当编译c++源文件的时候(只编译c++),传递给编译器的可选的标志集合。它们出现在LOCAL_CFLAGS之后的编译器的命令行上。
注意:在android-ndk-1.5_r1中,相应的flag同时运用于c和c++源代码。这些已经得到修正,以匹配整个Android编译系统。(现在你可以使用LOCAL_CFLAGS来指定c和c++源代码的标志)。
LOCAL_STATIC_LIBRARIES
应该链接到这个module的静态库modules(用BUILD_STATIC_LIBRARY编译)列表。这在共享库模块才有意义。
LOCAL_SHARED_LIBRARIES
运行时这个module依赖的动态共享库‘modules’列表。这个在链接的时候是有必要的,同时会在生成的文件中嵌入相应的信息。
LOCAL_WHOLE_STATIC_LIBRARIES
它是LOCAL_STATIC_LIBRARIES(用来表达相应library module)的一个变体,对于链接器它应该使用‘whole archives’。可以查看GNU 链接器的文档来了解–whole-archive这个标志。
当很多静态库之间中有环形依赖的时候,这个通常是非常有用的。注意当用它来编译动态库的时候,会强制将你的整个静态库中的所有对象文件添加到最终的二进制文件中。虽然在生成可执行文件的时候是不正确的。
LOCAL_LDLIBS
当编译module时,被使用的附加的链接器标志列表。使用“-l”前缀来传递指定系统库的名称是非常有用的。例如,下面这些将告诉链接器生成一个module,在加载的时候链接到/system/lib/libz.so。
LOCAL_LDLIBS := -lz
查看STABLE-APIS相关内容,了解这个NDK版本能够链接的系统库列表。
LOCAL_ALLOW_UNDEFINED_SYMBOLS
默认情况下,当试图编译动态库时,如果没有定义任何引用,将会导致“undefined symbol”的错误。这对在代码中捕捉bug是非常有帮助的。
然而由于某些原因你需要禁用这个检查,设置这个值为‘true’。注意对应的动态库可能在运行时会加载失败。
LOCAL_ARM_MODE
默认情况下,ARM目标二进制文件将生成在‘thumb’模式,其中每个指令是16位宽。如果你想强制生成‘arm’(32位指令)模式下module的对象文件,你可以定义这个变量为‘arm’。例如:
LOCAL_ARM_MODE := arm
注意你也可以在源文件加上后缀‘.arm’来告诉编译系统,你只想对某个源文件使用arm指令。例如:
告诉编译系统总是用ARM模式编译‘bar.c’,根据LOCAL_ARM_MODE的值编译foo.c。
注意:在Application.mk设置APP_OPTM为‘debug’,同样会强制生成ARM二进制文件。这是因为工具链调试器存在的一个bug,并没有很好的处理thumb代码。
LOCAL_ARM_NEON
定义这个变量为‘true’,允许在c和c++代码中使用ARM Advanced SIMD (又名 NEON)GCC指令,在组织文件中使用NEON指令。
只有目标为‘armeabi-v7a’ABI(对应于ARMv7指令集),才应该定义它。注意并不是所有基于ARMv7的CPUs都支持NEON指令集扩展,比较安全的做法是在运行时检测是否能够使用这个代码。如果要了解更多细节,请阅读CPU-ARM-NEON和CPU-FEATURES相关内容。
你也可以使用‘.neon’后缀指定某个特定的源文件支持NEON指令编译,例如:
在这个例子,‘foo.c’在thumb+neon模式下编译,‘bar.c’在‘thumb’模式下编译,‘zoo.c’在‘arm+neon’模式下编译。
注意‘.neon’后缀必须出现在‘.arm’的后面,如果你同时使用的话。(如foo.c.arm.neon可以工作,但是foo.c.neon.arm不行!)
LOCAL_DISABLE_NO_EXECUTE
Android NDK r4为“NX bit”的安全功能提供支持。默认这个是启用的,如果你确实需要禁用,可以设置这个变量为‘true’。
注意:这个功能不会修改ABI,只是在内核目标ARMv6+CPU的设备上启用。
想要了解更多信息,请看:
http://en.wikipedia.org/wiki/NX_bit
http://www.gentoo.org/proj/en/hardened/gnu-stack.xml
LOCAL_DISABLE_RELRO
默认情况下,NDK编译后的代码是只读的进行移动位置并得到GOT保护。这个会指示运行时链接器标记特定的内存区是只读的,在移动位置之后。这样会使得某些安全漏洞(如GOT覆盖)更难执行。
默认它是启用的,但是如果你确实需要,你可以禁用它通过设置变量为‘true’。
想要了解更多信息,请看:
LOCAL_EXPORT_CFLAGS
定义这个变量是为了记录c/c++编译器flags的集合,这些flags会被添加到任何其他module定义的LOCAL_CFLAGS中,而这个module通过LOCAL_STATIC_LIBRARIES 或者LOCAL_SHARED_LIBRARIES使用它。
例如,考虑module‘foo’下面的定义:
另一个module‘bar’,依赖于它:
当编译bar.c的时候,标志'-DFOO=1 -DBAR=2'将会传递给编译器。
Exported flags被加在你module的LOCAL_CFLAGS中,所以你可以简单的覆盖它们。它们也可以传递:如果‘zoo’依赖‘bar’,‘bar’依赖‘foo’,那么‘zoo’将继承‘foo’导出的所有flags。
最后,当编译的module导出它们时,exported flags不会被使用。在上面的例子中,当编译foo/foo.c时,-DFOO=1不会传递给编译器。
LOCAL_EXPORT_CPPFLAGS
和LOCAL_EXPORT_CFLAGS相同,但是只针对c++标志。
LOCAL_EXPORT_C_INCLUDES
和LOCAL_EXPORT_CFLAGS相同,但是它是针对c包含路径的。这是非常有用的,如果‘bar.c’想要包含module‘foo’提供的头文件。
LOCAL_EXPORT_LDLIBS
和LOCAL_EXPORT_CFLAGS相同,但是它是针对链接器标志的。注意由于Unix链接器的工作方式,被导入的链接器标志将append到你module的LOCAL_LDLIBS中。
这是非常有用的,当module‘foo’是一个静态库和它有代码依赖于系统库的时候。LOCAL_EXPORT_LDLIBS可以用来导出这个依赖关系。例如:
LOCAL_SHORT_COMMANDS
设置这个变量为‘true’,当你的module有很多的源文件,或者依赖很多的静态或动态库。这会强制编译系统使用一个中间的列表文件,并通过@$(listfile) 语法和library archiver 或者 static linker一起使用。
这在Windows上是非常有用的,因为它的命令行只接收最大8191个字符,这对于复杂的工程来说太小了。
注意如果设置了‘true’以外的值,都会恢复成默认行为。你也可以在Android.mk文件中定义APP_SHORT_COMMANDS来强制使你的工程中的所有modules使用这项功能。
注意:默认我们不推荐启用这个功能,因为它会使得编译变慢。
LOCAL_FILTER_ASM
为shell命令定义这个变量,将会过滤从你的LOCAL_SRC_FILES汇编或生成的文件。
当它被定义时,将发生下面的事情:
- 所有的c或者c++会生成到一个临时汇编文件(而不是编译进对象文件中)。
- 任何临时的、在LOCAL_SRC_FILES列出的汇编文件通过LOCAL_FILTER_ASM命令发送来生成另一个临时的汇编文件。
- 这些被过滤后的汇编文件被编译到对象文件中。
换句话说,如果你有:
“1”对应编译器,“2”对应过滤器,“3”对应汇编。过滤器必须是独立的shell命令,把输入文件的名称作为第一个参数,输出文件的名称作为第二个参数,例如: