Android NDK開發指南---Application.mk文件和android.mk文件


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 位於同一個目錄:
      [plain] view plain copy
      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的簡單例子如下:

      [plain] view plain copy
      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文件中編寫如下:

      [plain] view plain copy
      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:

      [plain] view plain copy
      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的兼容,但是反過來就不行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM