NDK Android.mk手册

来源:互联网 发布:游戏数据分析的艺术pdf 编辑:程序博客网 时间:2024/06/05 09:17

本文从$NDK/docs/ANDROID-MK.html文件翻译而来.


1 概述:

Android.mk文件是用来描述你的源码是如何编译的:

--Anddroid.mk在编译工程中有可能会被多次解析,因此,应尽量地在Android.mk文件中少声明变量,不要认为在解析过程中没有定义任何东西。

--Android.mk的语法用来组织你的源码使其模块化,每个模块可以是静态库(.a文件)或动态库(.so文件)。

动态库最终会被安装或拷贝到.apk文件内,而静态库用来生成动态库。

在一个Android.mk文件中可以定义一个或多个模块,且源文件可以各个模块中被重复使用。

Andoid编译系统会为你自动为你做一些比较细节的东西,比如,在Android.mk文件中你不必列出头文件和显式信赖,Android编译系统会自动找到对应的内容。这也意味着,当用更新ND有新版本编译时,你不必更改任何内容。

需要注意地是,NDK的Android.mk与Android源码下的Android.mk文件相常相似,但有些差别。NDK的Android.mk文件是特意如此设计,以便你更方便地使用外部库。

一个简单的示例:

在详细描述Android.mk的语法之前,让我们来看一个简单的"Hello JNI"的例子:

源文件位于 app/hello-jni/project目录下.

--  有一个src子目录,包含了java代码.

-- 有一个jni子目录包含了nativa代码(原生代码?).如:jni/hello-jni.c

这个文件实现了一个简单的动态库,在这个动态库内实现了一个native方法,它向java应用程序对应的虚拟机返回一个string.

jni/Android.mk文件则向NDK构建系统描述了如何编译这个jni动态库.它的内容如下:

---------- cut here ------------------   LOCAL_PATH := $(call my-dir)   include $(CLEAR_VARS)   LOCAL_MODULE    := hello-jni   LOCAL_SRC_FILES := hello-jni.c   include $(BUILD_SHARED_LIBRARY)   ---------- cut here ------------------
现在让我们来解释这些行:

LOCAL_PATH := $(call my-dir)
一个Android.mk文件必须以LOCAL_PATH定义开头,它用来定位源码。这当前这个例子中,宏“call my-dir”由构建内部系统提供,用来返回当前的路径,即包含Android.mk本身的当前目录.

include $(CLEAR_VARS)
这个CLEAR_VARS变量由NDK构建系统内部提供,它指向一个GNU Makefile文件,用来清除一个以LOCAL_开头的变量的值,但LOCAL_PATH除外,

LOCAL_MODULE := hello-jni
LOCAL_MOUDLE用来定义你的模块名,它的名字必须是唯一的。不能包含空格。需要注意地是,NDK构建系统会自动为所生成的目标模块加上前缀和扩展名,比如foo模块,最终终会生成libfoo.so文件。

需要注意地是,如果你为你的模块名加上lib前缀,则NDK构建系统则不会再加上lib前缀,也就是说,生成目标库时,NDK创建系统会自动判断是否需要加上lib前缀.

LOCAL_SRC_FILES := hello-jni.c
LOCAL_SRC_FILES必须包含C源码或C++源码。注:你不必列出所需要的头文件,NDK构建系统会自动为你找到对应的头文件。

另一个需要注意地是,默认C++的扩展名为cpp,但也可以通过变量LOCAL_CPP_EXTENSION来定义不同的扩展名,用这个变量时设置其值时千万别忘了第一个字符是点。如.cxx将生效,而cxx则不会.

include $(BUILD_SHARED_LIBRARY)
BUILD_SHARED_LIBARARY由NDK构建系统内容提供,它指向一个GNU Makefile脚本,负责收集此上次执行'include $(CLEAR_VARS)'以来的所有LOCAL_XXX变量信息,和决定最终生成什么,以及如何精确地构建动态库。BUILD_STATIC_LIBRARY与此类似,它则生成静态库.

还有一些更复杂的Android.mk示例在$NDK/samples目录下,下面的Andoird.mk文件内都有注释,你可以去看看.


2 参考

接下来将会列出一些在Andorid.mk文件中定义的变量,这些变量是编译系统提供的,当然你也可自定义变量,但是不要跟NDK编译系统预定的变量相冲突。

编译预定的变量名拥有以下规则:

- 以前缀LOCAL_开头  (如: LOCAL_MODULE)- 以前缀PRIVATE_, NDK_ or APP_开头  (系统内容使用)- 小写字母(内容使用, 如. 'my-dir')
如果你想自定义变量的话,建议使用前缀MY_,如:

 ---------- cut here ------------------    MY_SOURCES := foo.c    ifneq ($(MY_CONFIG_BAR),)      MY_SOURCES += bar.c    endif    LOCAL_SRC_FILES += $(MY_SOURCES)   ---------- cut here ------------------

2.1 NDK提供的变量:

GNU Make变量由NDK编译系统提供,并且在Android.mk文件被解析前就已经存在。Andorid.mk文件有可能被多次解析,因此,每次解析时这些变量的值都是可能不同的.

CLEAR_VARS

指向一个编译脚本,它将清除所有以LOCAL_前缀的变量,你必须在Android.mk文件的开头处使用它,如下:

include $(CLEAR_VARS)

BUILD_SHARED_LIBRARY


指向一个编译脚本,它将收集所有LOCAL_变量定义的信息,并决定如何生成目标动态库文件。在include 它之前,你必须先使用LOCAL_MODULE,LOCAL_SRC_FIELS定义模块名和源文件列表。使用方法如下:

include $(BUILD_SHARED_LIBRARY)
注:生成的文件为 lib$(LOCAL_MODULE).so

BUILD_STATIC_LIBRARY

BUILD_SHARED_LIBRARY的一个变种,用来生成静态库。静态库不会被拷贝到你的apk内,但它可以用来生成so文件,参考接下来将要介绍的变量

LOCAL_STATIC_LIBRARIES 和 LOCAL_WHOLE_STATIC_LIBRARIES,使用方法如下:

include $(BUILD_STATIC_LIBRARY)
注:使用它最终将生成lib$(LOCAL_MODULE).a文件.

PREBUILT_SHARED_LIBRARY

指向一个编译脚本,用来指定一个预编译动态库.使用此变量时,不像BUILD_SHARED_LIBRARY和BUILD_STATIC_LIBRARY那样,LOCAL_SRC_FILES的值必须是只能有一个指向预编译动态库的路径,如foo/libfoo.so,而不是源文件.

你可以通过LOCAL_PREBUILTS变量来引用一个预编译库.更多信息请参考文档:docs/PREBUILTS.html

PREBUILT_STATIC_LIBRARY

这个跟变量PREBUILT_SHARED_LIBRARY一样,只不过用来引用静态库.更多信息请参考文档:docs/PREBUILTS.html

TARGET_ARCH

目标CPU架构名。如果目标CPU是ARM兼容的架构,那么将此变量的值设为arm.

TARGET_PLATFORM

指定目标Android平台,例如:'android-3'对应着Android 1.5系统镜像,有关更多Android平台对应的Android系统,请参考:docs/STABLE-APIS.html.

TARGET_ARCH_ABI

目标CPU+ABI的名字。目前支持两个选择:

armeabi   ---ARMv5TE       armeabi-v7a

注:在Android NDK 1.6_r1之前,这个变量的值简单地被设置为'arm',然而它的值被重定义以便匹配目标Android平台.

更多信息请参考:docs/CPU-ARCH-ABIS.html

随着NDK版本的不断更新,将来NDK将会支持更多不同的ABI,需要注意地是,所有基于ARM ABI的文件的TARGET_ARCH变量的值都设置为arm,但TARGET_ARCH_ABI变量的值不同.

TARGET_ABI

目标平台和ABI连起来的名字.它的值为$(TARGET_PLATFORM)-$(TARGET_ARCH_ABI)的形式,当你在真实设备上测试指定系统镜像时将变得很有用.

默认情况五,它的值为'android-3-armeabi'.

注:在Android NDK 1.6_r1之前,它的默认值为'android-3-arm'。

2.2 NDK提供的宏:

这些宏将以'$(call <function>)'的形式被使用,它返回文本信息.

my-dir

返回当前Android.mk文件所在目录,在给LOCAL_PATH变量赋值时很有用.如:

LOCAL_PATH := $(call my-dir)

注:根据GNU Make的工作方式,此宏返回上一次包含使用include时所在的路径,不要在使用include 后再使用此宏。

例如:

[plain] view plaincopy
  1. LOCAL_PATH := $(call my-dir)  
  2. ... declare one module  
  3. include $(LOCAL_PATH)/foo/Android.mk  
  4. LOCAL_PATH := $(call my-dir)  
  5. ... declare another module  
上面的示例中,问题出现在第二个$(call my-dir)将会返回给LOCAL_PATH的路径是$PATH/foo ,而不是$PATH。因为在第二个$(call my-dir)之前使用了include的,而call my-dir返回的是之前最近一次的include所包含的路径.

出于这个原因,更好的方法是将include 放到文件末尾.如下所示:

[plain] view plaincopy
  1. LOCAL_PATH := $(call my-dir)  
  2. ... declare one module  
  3. LOCAL_PATH := $(call my-dir)  
  4. ... declare another module  
  5. <pre># extra includes at the end of the Android.mk  
  6. include $(LOCAL_PATH)/foo/Android.mk</pre>  
  7. <pre></pre>  
  8. <p></p>  
  9. <pre></pre>  
  10. 如果你觉得不方便的话,那么将第一个my-dir的值保存到一个变量里边,如下所示:  
  11. <p></p>  
  12. <p></p>  
  13. <pre name="code" class="plain">MY_LOCAL_PATH := $(call my-dir)  
  14. LOCAL_PATH := $(MY_LOCAL_PATH)  
  15. ... declare one module  
  16. include $(LOCAL_PATH)/foo/Android.mk  
  17. LOCAL_PATH := $(MY_LOCAL_PATH)  
  18. ... declare another module</pre>  
  19. <p></p>  
  20. <p></p>  
  21. <h3><a name="t14"></a>all-subdir-makefiles</h3>  
  22. 返回所有包含Android.mk的子目录。假设有这么一个结构:  
  23. <p></p>  
  24. <p></p>  
  25. <pre>sources/foo/Android.mk  
  26. sources/foo/lib1/Android.mk  
  27. sources/foo/lib2/Android.mk</pre>  
  28. 如果在sources/foo/Android.mk文件中包含了这么一行:  
  29. <p></p>  
  30. <p></p>  
  31. <pre>include $(call all-subdir-makefiles)</pre>  
  32. 它将自动包含sources/foo/lib1/Android.mk和sources/foo/lib2/Android.mk.  
  33. <p></p>  
  34. <p>这个功能可以用在深层次嵌套上。需要注意地是,NDK只会包含当前目录下的下一层目录。</p>  
  35. <p></p>  
  36. <h3><a name="t15"></a>this-makefile</h3>  
  37. 返回当前Makefile所在的目录.  
  38. <p></p>  
  39. <p></p>  
  40. <h3><a name="t16"></a>parent-makefile</h3>  
  41. 返回上一层Makefile所在的目录.  
  42. <p></p>  
  43. <p></p>  
  44. <h3><a name="t17"></a>grand-parent-makefile</h3>  
  45. 返回上两层Makefile所在的目录.  
  46. <p></p>  
  47. <p></p>  
  48. <h3><a name="t18"></a>import-module</h3>  
  49. 通过模块名找到另一个模块的Android.mk所在的目录.  
  50. <p></p>  
  51. <p>一个典型的用例如下:</p>  
  52. <p></p>  
  53. <pre>$(call import-module,<name>)</pre>  
  54. 这将在环境参数NDK_MODULE_PATH所定义的目录下通过模块名<name>寻找Android.mk所在的目录,并返回.有关更详情的说明,请参考文档:docs/IMPORT-MODULE.html<br>  
  55. <p></p>  
  56. <p><br>  
  57. </p>  
  58. <h2><a name="t19"></a>2.3 模块描述变量:</h2>  
  59. <p>接下来列出的变量是描述模块的变量。如果你要使用这些变量,请在语句include $(CLEAR_VARS)和include $(BUILD_XXXXX)之间使用这些变量。就如之前说过的那个CLEAR_VARS是指向一个脚本,用来清除所有LOCAL_XXX变量,但LOCAL_PATH例外.</p>  
  60. <p></p>  
  61. <h3><a name="t20"></a>LOCAL_PATH</h3>  
  62. 这个变量用来定义当前Android.mk所在的目录.可以通过下面这条语句来完成:  
  63. <p></p>  
  64. <p></p>  
  65. <pre>LOCAL_PATH := $(call my-dir)</pre>  
  66. 注:此变量不能被$(CLEAR_VARS)清除,所以每个Android.mk文件只需要定义一次就行了.  
  67. <p></p>  
  68. <p></p>  
  69. <h3><a name="t21"></a>LOCAL_MODULE</h3>  
  70. 你的模块名.它必须是唯一的,且中间不能有空格。你必须在$(BUILD_XXXX)之间定义它.  
  71. <p></p>  
  72. <p>在默认情况下,它决定了生成的文件名,如<foo>对应的动态库为libfoo.so,然而要索引它时,却只需要使用<foo>就行了.</p>  
  73. <p>你可以通过变量LOCAL_MODULE_FILENAME来覆盖这个默认情况.</p>  
  74. <p></p>  
  75. <h3><a name="t22"></a>LOCAL_MODULE_FILENAME</h3>  
  76. 这个变量是可选的,使你可以重定义你生成的文件。在默认情况下,模块<foo>即会生成静态库lib<foo>.a或者动态库lib<foo>.so.  
  77. <p></p>  
  78. <p>你可以通过变量LOCAL_MODULE_FILENAME来修改这种默认情况,如下所示:</p>  
  79. <p></p>  
  80. <pre>LOCAL_MODULE := foo-version-1  
  81. LOCAL_MODULE_FILENAME := libfoo</pre>  
  82. 注:你不必为LOCAL_MODULE_FILENAME指定路径或扩展名,编译系统将会自动完成这些工作.  
  83. <p></p>  
  84. <p></p>  
  85. <h3><a name="t23"></a>LOCAL_SRC_FILES</h3>  
  86. 此变量的值列出所有源文件,只需要列出源文件即可,不需要列出头文件,因此编译系统会自动为你找到所有所需的头文件。  
  87. <p></p>  
  88. <p>注:源文件是指相当前LOCAL_PATH的源文件,如果你的源文件不在这个变量所指的路径下,那么可以使用相对目录,如下:</p>  
  89. <p></p>  
  90. <pre>LOCAL_SRC_FILES := foo.c \  
  91.                          toto/bar.c</pre>  
  92. 注:路径要使用Unix风格的顺斜杠(/),而不是windows风格的反斜杠(\),编译系统不会处理反斜杠.  
  93. <p></p>  
  94. <p></p>  
  95. <h3><a name="t24"></a>LOCAL_CPP_EXTENSION</h3>  
  96. 此变量是可选的.用来指定C++后缀名.它必须以点开头,用来修改默认情况下的cpp后缀名.如:  
  97. <p></p>  
  98. <p></p>  
  99. <pre>LOCAL_CPP_EXTENSION := .cxx</pre>  
  100. 从NDK r7起,此变量可以同时列出多个C++后缀名.如:  
  101. <p></p>  
  102. <p></p>  
  103. <pre>LOCAL_CPP_EXTENSION := .cxx .cpp .cc</pre>  
  104. <h3><a name="t25"></a>LOCAL_CPP_FEATURES</h3>  
  105. 此变量是可选的,用来指定你的C++代码依赖指定的C++特性,如果你的C++使用RTTI (RunTime Type Information),则:  
  106. <p></p>  
  107. <p></p>  
  108. <pre>LOCAL_CPP_FEATURES := rtti</pre>  
  109. 如果你使用C++异常,则:  
  110. <p></p>  
  111. <p></p>  
  112. <pre>LOCAL_CPP_FEATURES := exceptions</pre>  
  113. 同时使用时则:(顺序无关紧要)  
  114. <p></p>  
  115. <p></p>  
  116. <pre>LOCAL_CPP_FEATURES := rtti features</pre>  
  117. 建议使用此变量,避免在LOCAL_CPPFLAGS直接使用-frtti 和 -fexceptions.  
  118. <p></p>  
  119. <p></p>  
  120. <h3><a name="t26"></a>LOCAL_C_INCLUDES</h3>  
  121. 此变量是可选的,用来列出所有头文件路径,路径是以NDK根目录为相对路径。如:  
  122. <p></p>  
  123. <p></p>  
  124. <pre>LOCAL_C_INCLUDES := sources/foo</pre>  
  125. 或者:  
  126. <p></p>  
  127. <p></p>  
  128. <pre>LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo</pre>  
  129. 此就是应该放于LOCAL_CFLAGS / LOCAL_CPPFLAGS之前。  
  130. <p></p>  
  131. <p>当使用ndk-gdb调试时,此变量列出的路径也将会被使用.</p>  
  132. <p></p>  
  133. <h3><a name="t27"></a>LOCAL_CFLAGS</h3>  
  134. 可选的编译标志。编译C代码或C++代码时将会使用到.  
  135. <p></p>  
  136. <p>重要注意:</p>  
  137. <p>不要在 Android.mk文件中优化等级或调试等级。这个将在Applicaiton.mk文件中精确定义.</p>  
  138. <p>在android-ndk-1.5_r1中,此变量只对C代码适用,而不适用C++代码.现在已经同时适用。你可以使用LOCAL_CPPFLAGS变量单独对C++代码有效.</p>  
  139. <p>在此变量中使用其它包含是可以生效的,如LOCAL_CFLAGS += -I<path>,但还是最好使用LOCAL_C_INCLUDES,因此后者对调试也同样适用.</p>  
  140. <p></p>  
  141. <h3><a name="t28"></a>LOCAL_CXXFLAGS</h3>  
  142. <p></p>  
  143. <p>LOCAL_CPPFLAGS的别名,不建议使用此变量,因为它将过时,将来不再使用.</p>  
  144. <p></p>  
  145. <h3><a name="t29"></a>LOCAL_CPPFLAGS</h3>  
  146. 此变量是可选的,只适用于C++代码。在编译器命令行一,它出现在LOCAL_CFLAGS之后,  
  147. <p></p>  
  148. <p>注:在android-ndk-1.5_r1,此变量同时适用于C和C++代码,出于匹配编译整个Android系统的原因,目前此变量仅仅适用于C++ 代码.</p>  
  149. <p></p>  
  150. <h3><a name="t30"></a>LOCAL_STATIC_LIBRARIES</h3>  
  151. <p></p>  
  152. <p>链接静态库.</p>  
  153. <p></p>  
  154. <h3><a name="t31"></a>LOCAL_SHARED_LIBRARIES</h3>  
  155. 列出所依赖的动态库.  
  156. <p></p>  
  157. <p></p>  
  158. <h3><a name="t32"></a>LOCAL_WHOLE_STATIC_LIBRARIES</h3>  
  159. <p></p>  
  160. <p>LOCAL_STATIC_LIBRARIES的变种,用来表示对应的库模块以“whole archives”被链接。相关详情请参考GNU链接器文档的--whole-archive标志说明.</p>  
  161. <p>当多个静态库循环依赖时,此变量变得非常有用。当生成动态库时,将会强制所有目标文件生成二进制文件.但在生成可执行文件时却不适用.</p>  
  162. <p></p>  
  163. <h3><a name="t33"></a>LOCAL_LDLIBS</h3>  
  164. 用于额外链接选项。这用以指定系统库时非常有用(-l前缀),例如,接下来的示例中,在生在模块时,这个链接选项将会告诉链接器在装载时链接到/system/lib/libz.so。  
  165. <p></p>  
  166. <p></p>  
  167. <pre>LOCAL_LDLIBS := -lz</pre>  
  168. 有关更多信息请参考文档:docs/STABLE-APIS.html  
  169. <p></p>  
  170. <p></p>  
  171. <h3><a name="t34"></a>LOCAL_ALLOW_UNDEFINED_SYMBOLS</h3>  
  172. 默认情况下,任何未定义的符号都将产生未定义的错误。这将帮你在源码中找到对应的错误。  
  173. <p></p>  
  174. <p>然而,出于某种原因你要关闭这个检查的功能时,将此变量设置为"true"即可,但是需要注意的是,即使如此,在装载so文件的时候也会出错.</p>  
  175. <p></p>  
  176. <h3><a name="t35"></a>LOCAL_ARM_MODE</h3>  
  177. 默认情况下,ARM目标二进制文件将会以"thumb"模式生成(16位指令),你可以将此变量设置为"arm",生成目标文件时将以"arm"模式生成(32位指令)。  
  178. <p></p>  
  179. <p></p>  
  180. <pre>LOCAL_ARM_MODE := arm</pre>  
  181. 注:你也可以通过在源文件加上".arm"后缀来指定这个源文件以"arm"模式编译。如:  
  182. <p></p>  
  183. <p></p>  
  184. <pre>LOCAL_SRC_FILES := foo.c bar.c.arm</pre>  
  185. 如上所示,bar.c.arm将以"arm"模式编译,而foo.c则取决于LOCAL_ARM_MODE的值.  
  186. <p></p>  
  187. <p>注:如果在Application.mk 文件中设置APP_OPTIM为“debug”,那个将强制以"arm"模式编译。因此调试器不能很好的支持"thumb"产生的目标文件.</p>  
  188. <p></p>  
  189. <h3><a name="t36"></a>LOCAL_ARM_NEON</h3>  
  190. 此变量设置为"true"的话,将允许你在C/C++中使用ARM 高级 SIMD (a.k.a. NEON) GCC intrinsics,就像汇编文件中的NEON指令.  
  191. <p></p>  
  192. <p>只有在使用'armeabi-v7a' ABI时使用此变量,注意不是所有的 基于armv7的CPU支持NEON指令集,更多详情请参考:docs/CPU-ARM-NEON.html 和 docs/CPU-FEATURES.html.</p>  
  193. <p>你也可以在源文件列表中列出的源文件后边加上后缀.neon来指定该源文件以NEON方式编译.如下所示:</p>  
  194. <p></p>  
  195. <pre>LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon</pre>  
  196. 在以下示例中,foo.c将会被以thumb+neon模式编译,bar.c将会以thumb方式编译,而zoo.c将以arm+neon方式编译.  
  197. <p></p>  
  198. <p>注意,后缀.neon是放到最后.</p>  
  199. <p></p>  
  200. <h3><a name="t37"></a>LOCAL_DISABLE_NO_EXECUTE</h3>  
  201. <p></p>  
  202. <p>Android NDK r4添加了支持"NX bit"的安全特性。在默认情况下此特性被激活,如果你不需要它,那么将此变量设置为"true"即可.</p>  
  203. <p>更多信息请参考:</p>  
  204. <p></p>  
  205. <pre>http://en.wikipedia.org/wiki/NX_bit  
  206. http://www.gentoo.org/proj/en/hardened/gnu-stack.xml</pre>  
  207. <h3><a name="t38"></a>LOCAL_EXPORT_CFLAGS</h3>  
  208. 使用此变量用来记录C/C++编译选项。  
  209. <p></p>  
  210. <p>例如:foo有如下定义:</p>  
  211. <p></p>  
  212. <pre>include $(CLEAR_VARS)  
  213. LOCAL_MODULE := foo  
  214. LOCAL_SRC_FILES := foo/foo.c  
  215. LOCAL_EXPORT_CFLAGS := -DFOO=1  
  216. include $(BUILD_STATIC_LIBRARY)</pre>  
  217. 它将生成libfoo.a文件。  
  218. <p></p>  
  219. <p>另一个模块bar有如下定义:</p>  
  220. <p></p>  
  221. <pre>include $(CLEAR_VARS)  
  222. LOCAL_MODULE := bar  
  223. LOCAL_SRC_FILES := bar.c  
  224. LOCAL_CFLAGS := -DBAR=2  
  225. LOCAL_STATIC_LIBRARIES := foo  
  226. include $(BUILD_SHARED_LIBRARY)</pre>  
  227.  它将生成libbar.so文件,libbar.so文件依赖libfoo.a静态库.  
  228. <p></p>  
  229. <p>编译器在编译bar.c源文件的时候,将会使用编译选项'-DFOO=1 -DBAR=2'.</p>  
  230. <p>由此可以看出,bar"继承"了foo的编译选项,同样,如果另一个模块zoo依赖foo,那么zoo将继承来看foo的LOCAL_EXPORT_CFLAGS编译选项.然而,定义LOCAL_EXPORT_CFLAGS定义的编译选项并不在定义此变量的模块本身中使用,如上所示,foo并没有使用LOCAL_EXPORT_CFLAGS编译选项.</p>  
  231. <p></p>  
  232. <h3><a name="t39"></a>LOCAL_EXPORT_CPPFLAGS</h3>  
  233. 与LOCAL_EXPORT_CFLAGS相同,只不过用于C++的编译选项.  
  234. <p></p>  
  235. <p></p>  
  236. <h3><a name="t40"></a>LOCAL_EXPORT_C_INCLUDES</h3>  
  237. 与LOCAL_EXPORT_CFLAGS相同,只不过用于C的包含路径.  
  238. <p></p>  
  239. <p>如果bar要包含foo的头文件时,这将很有用.</p>  
  240. <p></p>  
  241. <h3><a name="t41"></a>LOCAL_EXPORT_LDLIBS</h3>  
  242. 与LOCAL_EXPORT_CFLAGS相同,只不过用于链接选项.注:被导入的链接选项将会加入在变量LOCAL_LDLIBS定义的选项之前.  
  243. <p></p>  
  244. <p>来看一个例子:</p>  
  245. <p></p>  
  246. <pre>include $(CLEAR_VARS)  
  247. LOCAL_MODULE := foo  
  248. LOCAL_SRC_FILES := foo/foo.c  
  249. LOCAL_EXPORT_LDLIBS := -llog  
  250. include $(BUILD_STATIC_LIBRARY)</pre>  
  251. <p></p>  
  252. <p><br>  
  253. </p>  
  254. <p></p>  
  255. <pre>include $(CLEAR_VARS)  
  256. LOCAL_MODULE := bar  
  257. LOCAL_SRC_FILES := bar.c  
  258. LOCAL_STATIC_LIBRARIES := foo  
  259. include $(BUILD_SHARED_LIBRARY)</pre>  
  260. 这样,libfoo.so将使用链接选项 -llog, 因为它依赖libfoo.a.  
  261. <p></p>  
  262. <p></p>  
  263. <h3><a name="t42"></a>LOCAL_FILTER_ASM</h3>  
  264. 此变量指向一个shell指令,用来过滤汇编文件.使用此变量后,将会遵循以下规则:  
  265. <p></p>  
  266. <p>1:所有在LOCAL_SRC_FILES中列出的C/C++源文件首先将会被编译生成临时的汇编代码,而不是目标.o文件</p>  
  267. <p>2:所有生成的临时汇编文件和LOCAL_SRC_FILES列出的.S文件以LOCAL_FILTER_ASM进行过滤,然后生成另一个汇编文件.</p>  
  268. <p>3:最后经过过滤的汇编文件最终生成目标.o文件.</p>  
  269. <p>例如,假设有两个源代码文件:</p>  
  270. <p></p>  
  271. <pre>LOCAL_SRC_FILES  := foo.c bar.S  
  272. LOCAL_FILTER_ASM := myasmfilter</pre>  
  273. <pre>foo.c --1--> $OBJS_DIR/foo.S.original --2--> $OBJS_DIR/foo.S --3--> $OBJS_DIR/foo.o  
  274. bar.S                                 --2--> $OBJS_DIR/bar.S --3--> $OBJS_DIR/bar.o</pre>  
  275. 上面--1--->对应着编译器.  
  276. <p></p>  
  277. <p>---2--->对应着本变量定义的过滤器.</p>  
  278. <p>---3--->对应着汇编器.</p>  
  279. <p>本变量定义的过滤器必须是独立的shell指令,以汇编源码文件为第一个输入参数,第二个参数为输出文件参数。</p>  
  280. <p>即:</p>  
  281. <p></p>  
  282. <pre>myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S  
  283. myasmfilter bar.S $OBJS_DIR/bar.S</pre>  
  284. <br>  
  285. <p></p>  
  286. <p><br>  
  287. </p>  
  288. <p><br>  
  289. </p>  
  290. <p><br>  
  291. </p>  
  292. <pre></pre>  
  293. <p></p>  
0 0
原创粉丝点击