Android NDK开发指南---Application.mk文件和android.mk文件

时间:2021-09-22 13:11:32

https://android.googlesource.com/platform/development/+/donut-release/ndk/docs/OVERVIEW.TXT

https://android.googlesource.com/platform/ndk/+/4e159d95ebf23b5f72bb707b0cb1518ef96b3d03/docs/ANDROID-MK.TXT

https://android.googlesource.com/platform/ndk/+/4e159d95ebf23b5f72bb707b0cb1518ef96b3d03/docs/APPLICATION-MK.TXT

http://hualang.iteye.com/blog/1149359

http://blog.csdn.net/smfwuxiao/article/details/8523479

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

LOCAL_LDLIBS :链接的库不产生依赖关系,一般用于不需要重新编译的库,如库不存在,则会报错找不到。且貌似只能链接那些存在于系统目录下本模块需要连接的库。如果某一个库既有动态库又有静态库,那么在默认情况下是链接的动态库而非静态库。

如:LOCAL_LDLIBS += -lm –lz –lc -lcutils –lutils –llog …
如果你的Android.mk文件中只有这么一行,那么将会采用动态链接。
LOCAL_SHARED_LIBRARIES 会生成依赖关系,当库不存在时会去编译这个库。
LOCAL_LDFLAGS:这个编译变量传递给链接器一个一些额外的参数,比如想传递给外面的库和库路径给ld,或者传递给ld
linker的一些链接参数,-On,-EL{B}(大小端字节序),那么就要加到这个上面,如:
LOCAL_LDFLAGS += -L$(LOCAL_PATH)/lib/ -lHWrecog –EB{EL} –O{n}

或者直接加上绝对路径库的全名:
LOCAL_LDFLAGS += $(LOCAL_PATH)/lib/libHWrecog.a –EB{EL} –O{n}

===========================================================================

ndk-build命令行参数

1、ndk-build NDK_LOG=1

用于配置LOG级别,打印ndk编译时的详细输出信息

2、ndk-build NDK_PROJECT_PATH=.

指定NDK编译的代码路径为当前目录,如果不配置,则必须把工程代码放到Android工程的jni目录下

3、ndk-build APP_BUILD_SCRIPT=./Android.mk

指定NDK编译使用的Android.mk文件

4、ndk-build NDK_APPLICATION_MK=./Application.mk

指定NDK编译使用的application.mk文件

5、ndk-build clean

清除所有编译出来的临时文件和目标文件

6、ndk-build -B

强制重新编译已经编译完成的代码

7、ndk-build NDK_DEBUG=1

执行 debug build

8、ndk-build NDK_DEBUG=0

执行 release build

9、ndk-build NDK_OUT=./mydir

指定编译生成的文件的存放位置

10、ndk-build -C /opt/myTest/

到指定目录编译native代码

  1. Android NDK Overview
  2. Introduction:
  3. The Android NDK is a set of tools that allows Android application developers
  4. to embed native machine code compiled from C and/or C++ source files into
  5. their application packages.
  6. IMPORTANT:
  7. The Android NDK can only be used to target Android system images
  8. running Cupcake (a.k.a 1.5) or later versions of the platform.
  9. 1.0 and 1.1 system images are specifically *not* supported due to
  10. subtle ABI and toolchain changes that happened for the 1.5 release.
  11. I. Android NDK Goals:
  12. ---------------------
  13. The Android VM allows your application's source code to call methods
  14. implemented in native code through the JNI. In a nutshell, this means that:
  15. - Your application's source code will declare one or more methods
  16. with the 'native' keyword to indicate that they are implemented through
  17. native code. E.g.:
  18. native byte[] loadFile(String filePath);
  19. - You must provide a native shared library that contains the
  20. implementation of these methods, which will be packaged into your
  21. application's .apk. This library must be named according to standard
  22. Unix conventions as lib<something>.so, and shall contain a standard JNI
  23. entry point (more on this later). For example:
  24. libFileLoader.so
  25. - Your application must explicitely load the library. For example, to load
  26. it at application startup, simply add the following to its source code:
  27. static {
  28. System.loadLibrary("FileLoader");
  29. }
  30. Note that you should not use the 'lib' prefix and '.so' suffix here.
  31. The Android NDK is a complement to the Android SDK that helps you to:
  32. - Generate JNI-compatible shared libraries that can run on the Android
  33. 1.5 platform (and later) running on ARM CPUs.
  34. - Copy the generated shared libraries to a proper location of your
  35. application project path, so they will be automatically added to your
  36. final (and signed) .apks
  37. - In later revisions of the NDK, we intend to provide tools that help
  38. debug your native code through a remote gdb connection and as much
  39. source/symbol information as possible.
  40. Moreover, the Android NDK provides:
  41. - A set of cross-toolchains (compilers, linkers, etc..) that can
  42. generate native ARM binaries on Linux, OS X and Windows (with Cygwin)
  43. - A set of system headers corresponding to the list of stable native APIs
  44. supported by the Android platform. This corresponds to definitions that
  45. are guaranteed to be supported in all later releases of the platform.
  46. They are documented in the file docs/STABLE-APIS.TXT
  47. IMPORTANT:
  48. Keep in mind that most of the native system libraries in Android system
  49. images are not frozen and might changed drastically, or even deleted,
  50. in later updates and releases of the platform.
  51. - A build system that allow developers to only write very short build files
  52. to describe which sources need to be compiled, and how. The build system
  53. deals with all the hairy toolchain/platform/CPU/ABI specifics. Moreover,
  54. later updates of the NDK can add support for more toolchains, platforms,
  55. system interfaces without requiring changes in the developer's build
  56. files (more on this later).
  57. II. Android NDK Non-Goals:
  58. --------------------------
  59. The NDK is *not* a good way to write generic native code that runs on Android
  60. devices. In particular, your applications should still be written in the Java
  61. programming language, handle Android system events appropriately to avoid the
  62. "Application Not Responding" dialog or deal with the Android application
  63. life-cycle.
  64. Note however that is is possible to write a sophisticated application in
  65. native code with a small "application wrapper" used to start/stop it
  66. appropriately.
  67. A good understanding of JNI is highly recommended, since many operations
  68. in this environment require specific actions from the developers, that are
  69. not necessarily common in typical native code. These include:
  70. - Not being able to directly access the content of VM objects through
  71. direct native pointers. E.g. you cannot safely get a pointer to a
  72. String object's 16-bit char array to iterate over it in a loop.
  73. - Requiring explicit reference management when the native code wants to
  74. keep handles to VM objects between JNI calls.
  75. The NDK only provides system headers for a very limited set of native
  76. APIs and libraries supported by the Android platform. While a typical
  77. Android system image includes many native shared libraries, these should
  78. be considered an implementation detail that might change drastically between
  79. updates and releases of the platform.
  80. If an Android system library is not explicitely supported by the NDK
  81. headers, then applications should not depend on it being available, or
  82. they risk breaking after the next over-the-air system update on various
  83. devices.
  84. Selected system libraries will gradually be added to the set of stable NDK
  85. APIs.
  86. III. NDK development in practice:
  87. ---------------------------------
  88. Here's a very rough overview of how you can develop native code with the
  89. Android NDK:
  90. 1/ Run build/host-setup.sh to configure the NDK
  91. 2/ Place your native sources under $PROJECT/jni/...
  92. 3/ Write $PROJECT/jni/Android.mk to describe your sources
  93. to the NDK build system
  94. 4/ Write apps/<myapp>/Application.mk to describe your application
  95. and the native sources it needs to the NDK build system
  96. 5/ Build your native code by running "make APP=<myapp>"
  97. in the top-level NDK directory.
  98. The last step will copy, in case of success, the stripped shared libraries
  99. your application needs to your application's root project directory. You
  100. will then need to generate your final .apk through the usual means.
  101. Now, for a few more details:
  102. III.1/ Configuring the NDK:
  103. - - - - - - - - - - - - - -
  104. After installing the NDK as described in docs/INSTALL.TXT, you should call
  105. the 'build/host-setup.sh' script to configure your NDK.
  106. This script is used to probe your host system and verify a few pre-requisites.
  107. It will then generate a configuration file (e.g. out/host/config-host.mk) that
  108. is later used during NDK builds.
  109. In some cases, this might instruct you to download an archive containing
  110. prebuilt toolchain binaries for your development platform, the unzip it
  111. to the NDK root directory. The message should contain enough information
  112. to let you do that.
  113. If you forget this step, trying to build with the NDK will generate an
  114. error message telling you what to do.
  115. III.2/ Placing C and C++ sources:
  116. - - - - - - - - - - - - - - - - -
  117. You should place your native sources under the following directory:
  118. $PROJECT/jni/
  119. Where $PROJECT corresponds to the path of your Android application
  120. project.
  121. You are pretty free to organize the content of 'jni' as you want,
  122. the directory names and structure here will not influence the final
  123. generated application packages, so you don't have to use pseudo-unique
  124. names like com.<mycompany>.<myproject> as is the case for application
  125. package names.
  126. Note that C and C++ sources are supported. The default C++ file extensions
  127. supported by the NDK is '.cpp', but other extensions can be handled as well
  128. (see docs/ANDROID-MK.TXT for details).
  129. It is possible to store your sources in a different location by adjusting
  130. your Android.mk file (see below).
  131. III.3/ Writing an Android.mk build script:
  132. - - - - - - - - - - - - - - - - - - - - - -
  133. An Android.mk file is a small build script that you write to describe your
  134. sources to the NDK build system. Its syntax is described in details in
  135. the file docs/ANDROID-MK.TXT.
  136. In a nutshell, the NDK groups your sources into "modules", where each module
  137. can be one of the following:
  138. - a static library
  139. - a shared library
  140. You can define several modules in a single Android.mk, or you can write
  141. several Android.mk files, each one defining a single module.
  142. Note that a single Android.mk might be parsed several times by the build
  143. system so don't assume that certain variables are not defined in them.
  144. By default, the NDK will look for the following build script:
  145. $PROJECT/jni/Android.mk
  146. If you want to define Android.mk files in sub-directories, you should
  147. include them explicitely in your top-level Android.mk. There is even
  148. a helper function to do that, i.e. use:
  149. include $(call all-subdir-makefiles)
  150. This will include all Android.mk files in sub-directories of the current
  151. build file's path.
  152. III.4/ Writing an Application.mk build file:
  153. - - - - - - - - - - - - - - - - - - - - - - -
  154. While an Android.mk file describes your modules to the build system, you
  155. need to write an Application.mk file to describe your application and the
  156. modules it requires. This file must be located in:
  157. $NDK/apps/<myapp>/Application.mk
  158. Where <myapp> is a short descriptive name for your application that will
  159. be used to invoke the NDK build (and not go into final APKs). The file is
  160. used to provide the following to the NDK build:
  161. - The location of your Android application's project path
  162. - The list of NDK modules that is required by your application.
  163. This should really be a list of 'shared library' modules.
  164. - Optional information, like whether you want a release or debug
  165. build, specific C or C++ compiler flags and others.
  166. - Planned: the list of specific platforms/CPUs you want to explicitely
  167. target (currently only one is supported).
  168. The syntax of an Application.mk file is very simple and is described in
  169. docs/APPLICATION-MK.TXT
  170. You can define several Application.mk corresponding to different builds
  171. of the same application, for example:
  172. $NDK/apps/release/Application.mk
  173. $NDK/apps/debug/Application.mk
  174. III.5/ Invoke the NDK build system:
  175. - - - - - - - - - - - - - - - - - -
  176. On the command-line, go to the top-level NDK directory, then invoke the
  177. build system with:
  178. make APP=<myapp>
  179. Where 'make' refers to GNU Make, and <myapp> is the name of one of the
  180. subdirectories of '$NDK/apps/'
  181. This will try to build all modules with relevant options, the final
  182. shared libraries listed by your Application.mk and, in case of success,
  183. will copy stripped versions of the shared libraries to your application's
  184. project path. (Note that unstripped versions are kept for debugging
  185. purposes, there is no need to copy unstripped binaries to a device).
  186. IV. Debugging support:
  187. - - - - - - - - - - - -
  188. Debugging your native code with this initial release of the NDK is still
  189. very rough.
  190. Note that we plan to make this much easier in a later NDK release, all of
  191. this without changing your sources, Android.mk and Application.mk files.
  192. =========================
    1. Android.mk file syntax specification
    2. Introduction:
    3. -------------
    4. This document describes the syntax of Android.mk build file
    5. written to describe your C and C++ source files to the Android
    6. NDK. To understand what follows, it is assumed that you have
    7. read the docs/OVERVIEW.TXT file that explains their role and
    8. usage.
    9. Overview:
    10. ---------
    11. An Android.mk file is written to describe your sources to the
    12. build system. More specifically:
    13. - The file is really a tiny GNU Makefile fragment that will be
    14. parsed one or more times by the build system. As such, you
    15. should try to minimize the variables you declare there and
    16. do not assume that anything is not defined during parsing.
    17. - The file syntax is designed to allow you to group your
    18. sources into 'modules'. A module is one of the following:
    19. - a static library
    20. - a shared library
    21. Only shared libraries will be installed/copied to your
    22. application package. Static libraries can be used to generate
    23. shared libraries though.
    24. You can define one or more modules in each Android.mk file,
    25. and you can use the same source file in several modules.
    26. - The build system handles many details for you. For example, you
    27. don't need to list header files or explicit dependencies between
    28. generated files in your Android.mk. The NDK build system will
    29. compute these automatically for you.
    30. This also means that, when updating to newer releases of the NDK,
    31. you should be able to benefit from new toolchain/platform support
    32. without having to touch your Android.mk files.
    33. Note that the syntax is *very* close to the one used in Android.mk files
    34. distributed with the full open-source Android platform sources. While
    35. the build system implementation that uses them is different, this is
    36. an intentional design decision made to allow reuse of 'external' libraries'
    37. source code easier for application developers.
    38. Simple example:
    39. ---------------
    40. Before describing the syntax in details, let's consider a simple
    41. "hello world" example, i.e. the following files:
    42. sources/helloworld/helloworld.c
    43. sources/helloworld/Android.mk
    44. Where 'helloworld.c' is the source of a simple JNI shared library
    45. that implements a native method that returns the "hello world"
    46. string.
    47. The corresponding Android.mk file will look like this:
    48. ---------- cut here ------------------
    49. LOCAL_PATH := $(call my-dir)
    50. include $(CLEAR_VARS)
    51. LOCAL_MODULE := helloworld
    52. LOCAL_SRC_FILES := helloworld.c
    53. include $(BUILD_SHARED_LIBRARY)
    54. ---------- cut here ------------------
    55. Now, let's explain these lines:
    56. LOCAL_PATH := $(call my-dir)
    57. An Android.mk file must begin with the definition of the LOCAL_PATH variable.
    58. It is used to locate source files in the development tree. In this example,
    59. the macro function 'my-dir', provided by the build system, is used to return
    60. the path of the current directory (i.e. the directory containing the
    61. Android.mk file itself).
    62. include $(CLEAR_VARS)
    63. The CLEAR_VARS variable is provided by the build system and points to a
    64. special GNU Makefile that will clear many LOCAL_XXX variables for you
    65. (e.g. LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, etc...),
    66. with the exception of LOCAL_PATH. This is needed because all build
    67. control files are parsed in a single GNU Make execution context where
    68. all variables are global.
    69. LOCAL_MODULE := helloworld
    70. The LOCAL_MODULE variable must be defined to identify each module you
    71. describe in your Android.mk. The name must be *unique* and not contain
    72. any spaces. Note that the build system will automatically add proper
    73. prefix and suffix to the corresponding generated file. In other words,
    74. a shared library module named 'foo' will generate 'libfoo.so'.
    75. IMPORTANT NOTE:
    76. If you name your module 'libfoo', the build system will not
    77. add another 'lib' prefix and will generate libfoo.so as well.
    78. This is to support Android.mk files that originate from the
    79. Android platform sources, would you need to use these.
    80. LOCAL_SRC_FILES := helloworld.c
    81. The LOCAL_SRC_FILES variables must contain a list of C and/or C++ source
    82. files that will be built and assemble into a module. Note that you should
    83. not list header and included files here, because the build system will
    84. compute dependencies automatically for you; just list the source files
    85. that will be passed directly to a compiler, and you should be good.
    86. Note that the default extension for C++ source files is '.cpp'. It is
    87. however possible to specify a different one by defining the variable
    88. LOCAL_DEFAULT_CPP_EXTENSION. Don't forget the initial dot (i.e. '.cxx'
    89. will work, but not 'cxx').
    90. include $(BUILD_SHARED_LIBRARY)
    91. The BUILD_SHARED_LIBRARY is a variable provided by the build system that
    92. points to a GNU Makefile script that is in charge of collecting all the
    93. information you defined in LOCAL_XXX variables since the latest
    94. 'include $(CLEAR_VARS)' and determine what to build, and how to do it
    95. exactly. There is also BUILD_STATIC_LIBRARY to generate a static library.
    96. There are more complex examples under sources/samples, with commented
    97. Android.mk files that you can look at.
    98. Reference:
    99. ----------
    100. This is the list of variables you should either rely on or define in
    101. an Android.mk. You can define other variables for your own usage, but
    102. the NDK build system reserves the following variable names:
    103. - names that begin with LOCAL_ (e.g. LOCAL_MODULE)
    104. - names that begin with PRIVATE_, NDK_ or APP_ (used internally)
    105. - lower-case names (used internally, e.g. 'my-dir')
    106. If you need to define your own convenience variables in an Android.mk
    107. file, we recommend using the MY_ prefix, for a trivial example:
    108. ---------- cut here ------------------
    109. MY_SOURCES := foo.c
    110. ifneq ($(MY_CONFIG_BAR),)
    111. MY_SOURCES += bar.c
    112. endif
    113. LOCAL_SRC_FILES += $(MY_SOURCES)
    114. ---------- cut here ------------------
    115. So, here we go:
    116. NDK-provided variables:
    117. - - - - - - - - - - - -
    118. These GNU Make variables are defined by the build system before
    119. your Android.mk file is parsed. Note that under certain circumstances
    120. the NDK might parse your Android.mk several times, each with different
    121. definition for some of these variables.
    122. CLEAR_VARS
    123. Points to a build script that undefines nearly all LOCAL_XXX variables
    124. listed in the "Module-description" section below. You must include
    125. the script before starting a new module, e.g.:
    126. include $(CLEAR_VARS)
    127. BUILD_SHARED_LIBRARY
    128. Points to a build script that collects all the information about the
    129. module you provided in LOCAL_XXX variables and determines how to build
    130. a target shared library from the sources you listed. Note that you
    131. must have LOCAL_MODULE and LOCAL_SRC_FILES defined, at a minimum before
    132. including this file. Example usage:
    133. include $(BUILD_SHARED_LIBRARY)
    134. note that this will generate a file named lib$(LOCAL_MODULE).so
    135. BUILD_STATIC_LIBRARY
    136. A variant of BUILD_SHARED_LIBRARY that is used to build a target static
    137. library instead. Static libraries are not copied into your
    138. project/packages but can be used to build shared libraries (see
    139. LOCAL_STATIC_LIBRARIES and LOCAL_STATIC_WHOLE_LIBRARIES described below).
    140. Example usage:
    141. include $(BUILD_STATIC_LIBRARY)
    142. Note that this will generate a file named lib$(LOCAL_MODULE).a
    143. TARGET_ARCH
    144. Name of the target CPU architecture as it is specified by the
    145. full Android open-source build. This is 'arm' for any ARM-compatible
    146. build, independent of the CPU architecture revision.
    147. TARGET_PLATFORM
    148. Name of the target Android platform when this Android.mk is parsed.
    149. For now, only 'android-1.5' is supported.
    150. TARGET_ARCH_ABI
    151. Name of the target CPU+ABI when this Android.mk is parsed.
    152. For now, only 'arm' is supported, which really means the following:
    153. ARMv5TE or higher CPU, with 'softfloat' floating point support
    154. Other target ABIs will be introduced in future releases of the NDK
    155. and will have a different name. Note that all ARM-based ABIs will
    156. have 'TARGET_ARCH' defined to 'arm', but may have different
    157. 'TARGET_ARCH_ABI'
    158. TARGET_ABI
    159. The concatenation of target platform and abi, it really is defined
    160. as $(TARGET_PLATFORM)-$(TARGET_ARCH_ABI) and is useful when you want
    161. to test against a specific target system image for a real device.
    162. By default, this will be 'android-1.5-arm'
    163. NDK-provided function macros:
    164. - - - - - - - - - - - - - - -
    165. The following are GNU Make 'function' macros, and must be evaluated
    166. by using '$(call <function>)'. They return textual information.
    167. my-dir
    168. Returns the path of the current Android.mk's directory, relative
    169. to the top of the NDK build system. This is useful to define
    170. LOCAL_PATH at the start of your Android.mk as with:
    171. LOCAL_PATH := $(call my-dir)
    172. all-subdir-makefiles
    173. Returns a list of Android.mk located in all sub-directories of
    174. the current 'my-dir' path. For example, consider the following
    175. hierarchy:
    176. sources/foo/Android.mk
    177. sources/foo/lib1/Android.mk
    178. sources/foo/lib2/Android.mk
    179. If sources/foo/Android.mk contains the single line:
    180. include $(call all-subdir-makefiles)
    181. Then it will include automatically sources/foo/lib1/Android.mk and
    182. sources/foo/lib2/Android.mk
    183. This function can be used to provide deep-nested source directory
    184. hierarchies to the build system. Note that by default, the NDK
    185. will only look for files in sources/*/Android.mk
    186. this-makefile
    187. Returns the path of the current Makefile (i.e. where the function
    188. is called).
    189. parent-makefile
    190. Returns the path of the parent Makefile in the inclusion tree,
    191. i.e. the path of the Makefile that included the current one.
    192. grand-parent-makefile
    193. Guess what...
    194. Module-description variables:
    195. - - - - - - - - - - - - - - -
    196. The following variables are used to describe your module to the build
    197. system. You should define some of them between an 'include $(CLEAR_VARS)'
    198. and an 'include $(BUILD_XXXXX)'. As written previously, $(CLEAR_VARS) is
    199. a script that will undefine/clear all of these variables, unless explicitely
    200. noted in their description.
    201. LOCAL_PATH
    202. This variable is used to give the path of the current file.
    203. You MUST define it at the start of your Android.mk, which can
    204. be done with:
    205. LOCAL_PATH := $(call my-dir)
    206. This variable is *not* cleared by $(CLEAR_VARS) so only one
    207. definition per Android.mk is needed (in case you define several
    208. modules in a single file).
    209. LOCAL_MODULE
    210. This is the name of your module. It must be unique among all
    211. module names, and shall not contain any space. You MUST define
    212. it before including any $(BUILD_XXXX) script.
    213. The module name determines the name of generated files, e.g.
    214. lib<foo>.so for a shared library module named <foo>. However
    215. you should only refer to other modules with their 'normal'
    216. name (e.g. <foo>) in your NDK build files (either Android.mk
    217. or Application.mk)
    218. LOCAL_SRC_FILES
    219. This is a list of source files that will be built for your module.
    220. Only list the files that will be passed to a compiler, since the
    221. build system automatically computes dependencies for you.
    222. Note that source files names are all relative to LOCAL_PATH and
    223. you can use path components, e.g.:
    224. LOCAL_SRC_FILES := foo.c \
    225. toto/bar.c
    226. NOTE: Always use Unix-style forward slashes (/) in build files.
    227. Windows-style back-slashes will not be handled properly.
    228. LOCAL_CPP_EXTENSION
    229. This is an optional variable that can be defined to indicate
    230. the file extension of C++ source files. The default is '.cpp'
    231. but you can change it. For example:
    232. LOCAL_CPP_EXTENSION := .cxx
    233. LOCAL_CFLAGS
    234. An optional set of compiler flags that will be passed when building
    235. C source files (*not* C++ sources).
    236. This can be useful to specify an additionnal include path
    237. (relative to the top of the NDK directory), macro definitions
    238. or compile options.
    239. IMPORTANT: Try not to change the optimization/debugging level in
    240. your Android.mk, this can be handled automatically for
    241. you by specifying the appropriate information in
    242. your Application.mk, and will let the NDK generate
    243. useful data files used during debugging.
    244. LOCAL_CXXFLAGS
    245. Same as LOCAL_CFLAGS for C++ source files
    246. LOCAL_CPPFLAGS
    247. Same as LOCAL_CFLAGS but used for both C and C++ source files
    248. LOCAL_STATIC_LIBRARIES
    249. The list of static libraries modules (built with BUILD_STATIC_LIBRARY)
    250. that should be linked to this module. This only makes sense in
    251. shared library modules.
    252. LOCAL_SHARED_LIBRARIES
    253. The list of shared libraries *modules* this module depends on at runtime.
    254. This is necessary at link time and to embed the corresponding information
    255. in the generated file.
    256. Note that this does not append the listed modules to the build graph,
    257. i.e. you should still add them to your application's required modules
    258. in your Application.mk
    259. ===================
    1. Application.mk file syntax specification
    2. This document explains the Application.mk build file, which describes the native modules that your app requires. A module can be a static library, a shared library, or an executable.

      We recommend that you read the Concepts and Android.mk pages before this one. Doing so will help maximize your understanding of the material on this page.

      Overview


      The Application.mk file is really a tiny GNU Makefile fragment that defines several variables for compilation. It usually resides under $PROJECT/jni/, where $PROJECT points to your application's project directory. Another alternative is to place it under a sub-directory of the top-level $NDK/apps/ directory. For example:
      $NDK/apps/<myapp>/Application.mk

      Here, <myapp> is a short name used to describe your app to the NDK build system. It doesn't actually go into your generated shared libraries or your final packages.

      Variables


      APP_PROJECT_PATH

      This variable stores the absolute path to your app's project-root directory. The build system uses this information to place stripped-down versions of the generated JNI shared libraries into a specific location known to the APK-generating tools.

      If you place your Application.mk file under $NDK/apps/<myapp>/, you must define this variable. If you place it under $PROJECT/jni/, it is optional.

      APP_OPTIM

      Define this optional variable as either release or debug. You use it to alter the optimization level when building your application's modules.

      Release mode is the default, and generates highly optimized binaries. Debug mode generates unoptimized binaries that are much easier to debug.

      Note that you can debug either release or debug binaries. Release binaries, however, provide less information during debugging. For example, the build system optimizes out some variables, preventing you from inspecting them. Also, code re-ordering can make it more difficult to step through the code; stack traces may not be reliable.

      Declaring android:debuggable in your application manifest's <application> tag will cause this variable to default to debug instead of release. Override this default value by setting APP_OPTIM to release.

      APP_CFLAGS

      This variable stores a set of C compiler flags that the build system passes to the compiler when compiling any C or C++ source code for any of the modules. You can use this variable to change the build of a given module according to the application that needs it, instead of having to modify the Android.mk file itself.

      All paths in these flags should be relative to the top-level NDK directory. For example, if you have the following setup:

      sources/foo/Android.mk
      sources/bar/Android.mk

      To specify in foo/Android.mk that you want to add the path to the bar sources during compilation, you should use:

      APP_CFLAGS += -Isources/bar

      Or, alternatively:

      APP_CFLAGS += -I$(LOCAL_PATH)/../bar

      -I../bar will not work since it is equivalent to -I$NDK_ROOT/../bar.

      Note: This variable only works on C, not C++, sources in android-ndk-1.5_r1. In all versions after that one, APP_CFLAGS matches the full Android build system.

      APP_CPPFLAGS

      This variable contains a set of C++ compiler flags that the build system passes to the compiler when building only C++ sources.

      Note: In android-ndk-1.5_r1, this variable works on both C and C++ sources. In all subsequent versions of the NDK, APP_CPPFLAGS now matches the full Android build system. For flags that apply to both C and C++ sources, use APP_CFLAGS.

      APP_LDFLAGS

      A set of linker flags that the build system passes when linking the application. This variable is only relevant when the build system is building shared libraries and executables. When the build system builds static libraries, it ignores these flags.

      APP_BUILD_SCRIPT

      By default, the NDK build system looks under jni/ for a file named Android.mk.

      If you want to override this behavior, you can define APP_BUILD_SCRIPT to point to an alternate build script. The build system always interprets a non-absolute path as relative to the NDK's top-level directory.

      APP_ABI

      By default, the NDK build system generates machine code for the armeabi ABI. This machine code corresponds to an ARMv5TE-based CPU with software floating point operations. You can use APP_ABI to select a different ABI. Table 1 shows the APP_ABI settings for different instruction sets.

      Table 1. APP_ABI settings for different instruction sets.

      Instruction set Value
      Hardware FPU instructions on ARMv7 based devices APP_ABI := armeabi-v7a
      ARMv8 AArch64 APP_ABI := arm64-v8a
      IA-32 APP_ABI := x86
      Intel64 APP_ABI := x86_64
      MIPS32 APP_ABI := mips
      MIPS64 (r6) APP_ABI := mips64
      All supported instruction sets APP_ABI := all

      Note: all is available starting from NDKr7.

      You can also specify multiple values by placing them on the same line, delimited by spaces. For example:

      APP_ABI := armeabi armeabi-v7a x86 mips

      For the list of all supported ABIs and details about their usage and limitations, refer to ABI Management.

      APP_PLATFORM

      This variable contains the name of the target Android platform. For example, android-3 specifies the Android 1.5 system images. For a complete list of platform names and corresponding Android system images, see Android NDK Native APIs.

      APP_STL

      By default, the NDK build system provides C++ headers for the minimal C++ runtime library (system/lib/libstdc++.so) provided by the Android system. In addition, it comes with alternative C++ implementations that you can use or link to in your own applications. Use APP_STL to select one of them. For information about the supported runtimes, and the features they offer, see NDK Runtimes and Features.

      APP_SHORT_COMMANDS

      The equivalent of LOCAL_SHORT_COMMANDS in Application.mk for your whole project. For more information, see the documentation for this variable on Android.mk.

      NDK_TOOLCHAIN_VERSION

      Define this variable as either 4.9 or 4.8 to select a version of the GCC compiler. Version 4.9 is the default for 64-bit ABIs, and 4.8 is the default for 32-bit ABIs. To select a version of Clang, define this variable as clang3.4, clang3.5, or clang. Specifying clang chooses the most recent version of Clang.

      APP_PIE

      Starting from Android 4.1 (API level 16), Android's dynamic linker supports position-independent executables (PIE). From Android 5.0 (API level 21), executables require PIE. To use PIE to build your executables, set the -fPIE flag. This flag makes it harder to exploit memory corruption bugs by randomizing code location. By default, ndk-build automatically sets this value to true if your project targets android-16 or higher. You may set it manually to either true or false.

      This flag applies only to executables. It has no effect when building shared or static libraries.

      Note: PIE executables cannot run on Android releases prior to 4.1.

      This restriction only applies to executables. It has no effect when building shared or static libraries.

      APP_THIN_ARCHIVE

      Sets the default value of LOCAL_THIN_ARCHIVE in the Android.mk file for all static library modules in this project. For more information, see the documentation for LOCAL_THIN_ARCHIVE on Android.mk.

    3. Application.mk文件

      简介:
      -----------------------------
      要将C\C++代码编译为SO文件,光有Android.mk文件还不行,还需要一个Application.mk文件。
      本文档是描述你的Android应用程序中需要的本地模块的Application.mk的语法使用,要明白如下。

      Application.mk目的是描述在你的应用程序中所需要的模块(即静态库或动态库)。

      Application.mk文件通常被放置在$PROJECT/jni/Application.mk下,$PROJECT指的是您的项目。

      另一种方法是将其放在顶层的子目录下:
      $NDK/apps目录下,例如:
      $NDK/apps/<myapp>/Application.mk

      <myapp>是一个简称,用于描述你的NDK编译系统的应用程序(这个名字不会生成共享库或者最终的包)

      下面是Application.mk中定义的几个变量。

      APP_PROJECT_PATH
      这个变量是强制性的,并且会给出应用程序工程的根目录的一个绝对路径。这是用来复制或者安装一个没有任何版本限制的JNI库,从而给APK生成工具一个详细的路径。

      APP_MODULES
      这个变量是可选的,如果没有定义,NDK将由在Android.mk中声明的默认的模块编译,并且包含所有的子文件(makefile文件)
      如果APP_MODULES定义了,它不许是一个空格分隔的模块列表,这个模块名字被定义在Android.mk文件中的LOCAL_MODULE中。注意NDK会自动计算模块的依赖

      注意:NDK在R4开始改变了这个变量的行为,再次之前:
       - 在您的Application.mk中,该变量是强制的
       - 必须明确列出所有需要的模块

      APP_OPTIM
      这个变量是可选的,用来定义“release”或"debug"。在编译您的应用程序模块的时候,可以用来改变优先级。

      “release”模式是默认的,并且会生成高度优化的二进制代码。"debug"模式生成的是未优化的二进制代码,但可以检测出很多的BUG,可以用于调试。

      注意:如果你的应用程序是可调试的(即,如果你的清单文件中设置了android:debuggable的属性是"true")。默认的是"debug"而不是"release"。这可以通过设置APP_OPTIM为"release"来将其覆盖。

      注意:可以在"release"和"debug"模式下一起调试,但是"release"模式编译后将会提供更少的BUG信息。在我们清楚BUG的过程
      中,有一些变量被优化了,或者根本就无法被检测出来,代码的重新排序会让这些带阿弥变得更加难以阅读,并且让这些轨迹更加不可靠。

      APP_CFLAGS
      当编译模块中有任何C文件或者C++文件的时候,C编译器的信号就会被发出。这里可以在你的应用中需要这些模块时,进行编译的调整,这样就不许要直接更改Android.mk为文件本身了

      重要警告:+++++++++++++++++++++++++++++++++++++++++++++++ + +
      +
      + 在这些编制中,所有的路径都需要于最顶层的NDK目录相对应。
      + 例如,如果您有以下设置:
      +
      +sources/foo/Android.mk
      +sources/bar/ Android.mk
      + 编译过程中,若要在foo/Android.mk中指定你要添加的路径到bar源代码中,
      + 你应该使用
      + APP_CFLAGS += -Isources/bar
      + 或者交替:
      + APP_CFLAGS += -I $(LOCAL_PATH )/../bar
      +
      + 使用'-l../bar/'将不会工作,以为它将等同于"-l$NDK_ROOT/../bar"
      ++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++
      注意:在Android的NDK 1.5_r1,只适用于C源文件,而不适合C++。
      这已得到纠正,以建立完整相匹配的Andr​​oid系统。

      APP_CXXFLAGS
      APP_CPPFLAGS的别名,已经考虑在将在未来的版本中废除了

      APP_CPPFLAGS
      当编译的只有C++源文件的时候,可以通过这个C++编译器来设置

      注意:在Android NDK-1.5_r1中,这个标志可以应用于C和C++源文件中。并且得到了纠正,以建立完整的与系统相匹配的Android编译系统。你先可也可以使用APP_CFLAGS来应用于C或者C++源文件中。
      建议使用APP_CFLAGS

      APP_BUILD_SCRIPT
      默认情况下,NDK编译系统会在$(APP_PROJECT_PATH)/jni目录下寻找名为Android.mk文件:
      $(APP_PROJECT_PATH)/jni/Android.mk

      如果你想覆盖此行为,你可以定义APP_BUILD_SCRIPT来指定一个备用的编译脚本。一个非绝对路径总是被解释为相对于NDK的顶层的目录。

      APP_ABI
      默认情况下,NDK的编译系统回味"armeabi"ABI生成机器代码。喜爱哪个相当于一个基于CPU可以进行浮点运算的ARMv5TE。你可以使用APP_ABI来选择一个不同的ABI。

      比如:为了在ARMv7的设备上支持硬件FPU指令。可以使用
      APP_ABI := armeabi-v7a

      或者为了支持IA-32指令集,可以使用
      APP_ABI := x86

      或者为了同时支持这三种,可以使用
      APP_ABI := armeabi armeabi-v7a x86

      APP_STL
      默认情况下,NDK的编译系统为最小的C++运行时库(/system/lib/libstdc++.so)提供C++头文件。
      然而,NDK的C++的实现,可以让你使用或着链接在自己的应用程序中。
      例如:
      APP_STL := stlport_static    --> static STLport library
      APP_STL := stlport_shared    --> shared STLport library
      APP_STL := system            --> default C++ runtime library

      下面是一个Application.mk文件的示例:
      APP_PROJECT_PATH := <path to project>

    4. =================================

    5. NDK提供的共享库(Prebuilt)

    6. Android NDK r5 开始支持预编译库(动态库和静态库),即程序能使用库的预编译版本。

      该特性可用于以下两方面:

      1)向第三方NDK开发人员发布你的共享库而不用提供源码。
      2)使用一个提前编译好的库(预编译库)来加速编译过程。

      本文说明该特性如何工作。

      I. 声明一个预编译库的模块

      对于Android编译工具而言,每个预编译库必须声明为一个独立的模块。这里举一个例子,假设 libfoo.so 文件与 Android.mk 位于同一个目录:

      1. LOCAL_PATH := $(call my-dir)
      2. include $(CLEAR_VARS)
      3. LOCAL_MODULE := foo-prebuilt
      4. LOCAL_SRC_FILES := libfoo.so
      5. include $(PREBUILT_SHARED_LIBRARY)

      按以下步骤声明这样一个模块:
      1. 给该模块取一个名字(这里是 foo-prebuilt)。这个名字不需要与预编译库自身的名字相同。
      2. 将 LOCAL_SRC_FILES 指定为你要提供的共享库的路径。通常,该路径是相对于 LOCAL_PATH 的路径。注意:必须保证共享库ABI的兼容性。
      3. 如果你的库是共享库,则包含 PREBUILT_SHARED_LIBRARY 而不是 BUILD_SHARED_LIBRARY;如果是静态库,则包含 PREBUILT_STATIC_LIBRARY。

      预编译模块不需要编译。该预编译模块会被拷贝到 $PROJECT/obj/local 下面,还会被拷贝到 $PROJECT/libs/<abi> 下面(这里的库被strip过)。

      II. 在其他模块中引用这个预编译库

      在依赖该预编译库的模块对应的Android.mk中,将预编译库的名字(前面取的)加入到 LOCAL_STATIC_LIBRARIES 或 LOCAL_SHARED_LIBRARIES 声明中。例如,一个使用上面libfoo.so的简单例子如下:

      1. include $(CLEAR_VARS)
      2. LOCAL_MODULE := foo-user
      3. LOCAL_SRC_FILES := foo-user.c
      4. LOCAL_SHARED_LIBRARIES := foo-prebuilt
      5. include $(BUILD_SHARED_LIBRARY)

      III. 将预编译库的头文件导出

      得到预编译库之后,一般需要它对应的头文件。例如前面的libfoo.so,它有对应的foo.h。编译依赖libfoo.so的模块时,需要将该
      头文件和它的路径提供给NDK编译系统。一种简单方法是,前面在定义该预编译库的时候,使用LOCAL_EXPORT_C_INCLUDES
      变量。例如,假设文件 foo.h 位于当前预编译模块所在目录的 include 子目录,则可以在预编译模块的Android.mk文件中编写如下:

      1. include $(CLEAR_VARS)
      2. LOCAL_MODULE := foo-prebuilt
      3. LOCAL_SRC_FILES := libfoo.so
      4. LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
      5. include $(PREBUILT_SHARED_LIBRARY)

      这个 LOCAL_EXPORT_C_INCLUDES 定义确保了任何依赖这个预编译库的模块会自动在自己的 LOCAL_C_INCLUDES 变量中增加到这个预编译库的include目录的路径,从而能够找到其中的头文件。

      IV. 调试预编译库

      建议你在预编译库中保留调试信息。位于 $PROJECT/libs/<abi> 的版本都是不含调试信息的(被NDK编译系统执行strip过的),调试版的库才能用于 ndk-gdb。

      V. 共享库ABI的选择

      如前所述,共享库与目标系统的ABI兼容性至关重要。应检查一下 TARGET_ARCH_ABI 的值,可以是以下值:
      armeabi        目标系统CPU是ARMv5TE或更高
      armeabi-v7a    目标系统CPU是ARMv7或更高
      x86            目标系统CPU是x86
      注意,armeabi-v7a的CPU可以很好地执行armeabi的程序。
      举一个例子,我们提供一个预编译库的两个版本,然后选择不同的ABI:

      1. include $(CLEAR_VARS)
      2. LOCAL_MODULE := foo-prebuilt
      3. LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfoo.so
      4. LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
      5. include $(PREBUILT_SHARED_LIBRARY)

      这里假设要拷贝的预编译库所在的目录结构如下:
          Android.mk            --> 编译这个预编译库的Android.mk
          armeabi/libfoo.so     --> armeabi版本的共享库
          armeabi-v7a/libfoo.so --> armeabi-v7a版本的共享库
          include/foo.h         --> 预编译库导出的头文件
      注意:你不必提供armeabi-v7a版本,因为armeabi版本的共享库能够被armeabi-v7a的兼容,但是反过来就不行。