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

  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. Introduction:
    3. -------------
    4. This document describes the syntax of Application.mk build files
    5. written to describe the native modules required by your Android
    6. application. 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. Readers of this document should have read docs/OVERVIEW.TXT and
    10. docs/ANDROID-MK.TXT
    11. Overview:
    12. ---------
    13. The purpose of Application.mk is to describe which native
    14. ‘modules‘ (i.e. static/shared libraries) are needed by your
    15. application.
    16. Each Application.mk must be placed under a sub-directory of
    17. the top-level apps directory, e.g.:
    18. $NDK/apps/<myapp>/Application.mk
    19. Where <myapp> is a short name used to describe your ‘application‘
    20. to the NDK build system (this name doesn‘t go into your generated
    21. shared libraries or your final packages).
    22. The Application.mk is really a tiny GNU Makefile fragment that must
    23. define a few variables:
    24. APP_MODULES
    25. This variable is mandatory and lists all the native modules
    26. (described through Android.mk files) that your application
    27. requires.
    28. This must be a space-separated list of module names as they
    29. appear in the LOCAL_MODULE definitions of Android.mk files
    30. APP_PROJECT_PATH
    31. This variable is mandatory and should give the *absolute*
    32. path to your Application‘s project root directory. This is used
    33. to copy/install stripped versions of the generated JNI shared
    34. libraries to a specific location known to the APK-generating tools.
    35. APP_OPTIM
    36. This optional variable can be defined to either ‘release‘ or
    37. ‘debug‘. This is used to alter the optimization level when
    38. building your application‘s modules.
    39. A ‘release‘ mode is the default, and will generate highly
    40. optimized binaries. The ‘debug‘ mode will generate un-optimized
    41. binaries which are much easier to debug.
    42. Note that it is possible to debug both ‘release‘ and ‘debug‘
    43. binaries, but the ‘release‘ builds tend to provide less information
    44. during debugging sessions: some variables are optimized out and
    45. can‘t be inspected, code re-ordering can make stepping through
    46. the code difficult, stack traces may not be reliable, etc...
    47. APP_CFLAGS
    48. A set of C compiler flags passed when compiling any C source code
    49. of any of the modules. This can be used to change the build of a given
    50. module depending on the application that needs it, instead of modifying
    51. the Android.mk file itself.
    52. IMPORTANT WARNING: +++++++++++++++++++++++++++++++++++++++++++++++++++
    53. +
    54. + All paths in these flags should be relative to the top-level NDK
    55. + directory. For example, if you have the following setup:
    56. +
    57. + sources/foo/Android.mk
    58. + sources/bar/Android.mk
    59. +
    60. + To specify in foo/Android.mk that you want to add the path to the
    61. + ‘bar‘ sources during compilation, you should use:
    62. +
    63. + APP_CFLAGS += -Isources/bar
    64. +
    65. + Or alternatively:
    66. +
    67. + APP_CFLAGS += -I$(LOCAL_PATH)/../bar
    68. +
    69. + Using ‘-I../bar‘ will *NOT* work since it will be equivalent to
    70. + ‘-I$NDK_ROOT/../bar‘ instead.
    71. +
    72. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    73. APP_CXXFLAGS
    74. Same as APP_CFLAGS for C++ sources.
    75. APP_CPPFLAGS
    76. Same as APP_CFLAGS but will be passed to both C and C++ sources
    77. A trivial Application.mk file would be:
    78. -------------- cut here -------------------------
    79. APP_MODULES := <list of modules>
    80. APP_PROJECT_PATH := <path to project>
    81. -------------- cut here -------------------------
    82. ============================
    83. 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>

    84. =================================

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

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

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

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

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

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

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

      [plain] view plaincopy

      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 plaincopy

      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 plaincopy

      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 plaincopy

      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的兼容,但是反过来就不行。

时间: 2024-10-25 10:03:34

Android NDK开发指南---Application.mk文件和android.mk文件的相关文章

Android NDK开发及调用标准linux动态库.so文件

源:Android NDK开发及调用标准linux动态库.so文件 预备知识及环境搭建 1.NDK(native development Kit)原生开发工具包,用来快速开发C.C++动态库,并能自动将so文件和java应用一起打包成apk.对应:jni层c++开发 2.Cygwin:是windows平台上模拟Linux运行环境的工具,即window平台上的linux环境工具,so文件需要在linux平台上编译运行.对应:arm linux平台 3.CDT:eclipse下的C/C++开发工具,

Windows下Android+NDK开发环境搭建(JDK[8u45]+Eclipse+Android SDK[r24.1.2]+ADT+NDK[r10d])

一.Android开发环境搭建 1.安装JDK. (1)简介:JDK,即Java Development Kit,是Java语言的软件开发工具包.JRE,即Java Runtime Environment,是Java的运行环境,是面向Java的使用者而非开发者. (2)下载:点击打开链接(Oracle官网),选择对应系统的版本,我下载的是jdk-8u45-windows-i586.exe. (3)安装:双击进行安装,程序刚安装时设置的安装目录为JDK的安装目录,中途需要设置JRE的安装目录.为进

android NDK开发编译C++文件出现Type &#39;jint&#39; could not be resolved和Unresolved inclusion: &lt;jni.h&gt;的解决办法

今天在编译android NDK工程的时候,在jni文件夹下的cpp文件中报了一大堆错误,诸如:Unresolved inclusion: <jni.h>.Type 'jint' could not be resolved.Type 'jintArray' could not be resolved等,根据经验,这样的错误肯定是没有包含相应的头文件导致的. 解决方案: 选中工程,右键->Properties,点击C/C++ General展开,点击Path and Symbols,在右边

Android NDK 开发(三)--常见错误锦集合Log的使用【转】

转载请注明出处:http://blog.csdn.net/allen315410/article/details/41826511  Android NDK开发经常因某些因素会出现一些意想不到的错误,很多时候调试这些错误的时候,显得比调试Java代码要复杂,一方面是导致错误的原因很多很杂,另一方面NDK开发涉及到C/C++代码的编写,很多程序员对此不熟悉.那么这篇博客就总结一下,在NDK开发中经常出现的一些问题,并且尝试提供一些正确的解决方案,方便在开发时能够快速定位到错误,更改错误,当然了,错

Android NDK 开发(四)java传递数据到C【转】

转载请注明出处:http://blog.csdn.net/allen315410/article/details/41845701 前面几篇文章介绍了Android NDK开发的简单概念.常见错误及处理和从第一个Hello World开始实际做一个简单的JNI开发示例,相信看完之后,大家对NDK开发有了一个概念上的认识了,那么接下来我们需要再深入一下NDK的开发,我们知道NDK开发就是使用JNI这层“协议”在Java和C之间起个“桥梁”的作用,将Java和Native C之间联立起来,让Java

Android NDK开发(三)——常见错误集锦以及LOG使用

转载请注明出处:http://blog.csdn.net/allen315410/article/details/41826511  Android NDK开发经常因某些因素会出现一些意想不到的错误,很多时候调试这些错误的时候,显得比调试Java代码要复杂,一方面是导致错误的原因很多很杂,另一方面NDK开发涉及到C/C++代码的编写,很多程序员对此不熟悉.那么这篇博客就总结一下,在NDK开发中经常出现的一些问题,并且尝试提供一些正确的解决方案,方便在开发时能够快速定位到错误,更改错误,当然了,错

Android NDK开发(四)——Java传递数据到C

转载请注明出处:http://blog.csdn.net/allen315410/article/details/41845701 前面几篇文章介绍了Android NDK开发的简单概念.常见错误及处理和从第一个Hello World开始实际做一个简单的JNI开发示例,相信看完之后,大家对NDK开发有了一个概念上的认识了,那么接下来我们需要再深入一下NDK的开发,我们知道NDK开发就是使用JNI这层"协议"在Java和C之间起个"桥梁"的作用,将Java和Nativ

Android NDK编程浅入深出之--Android.mk

    Android.mk Android.mk是一个向Android NDK构建系统描述NDK项目的GUN Makefile片段.它是每一个NDK项目的必备组件.构建系统希望它出现在jni子目录中.下面是hello-jni项目中Android.mk文件的内容. # Copyright (C) 2009 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License

windows下用ADT进行android NDK开发的详细教程(从环境搭建、配置到编译全过程)

郑重申明:如需转载本博客,请注明出处,谢谢! 这几天在学习android NDK的开发,那么首先让我们来看看android NDK开发的本质是什么. NDK(Native Development Kit),即本地开发工具,简单地说,就是在开发android应用程序的时候,在java类中调用native函数,而native函数的接口也是在java类中定义的,但是native函数最终由本地的C/C++代码实现.简单地说,就是在java中调用C/C++函数.至于为什么要用NDK,我总结了一下,大致有以