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代码
- Android NDK Overview
- Introduction:
- The Android NDK is a set of tools that allows Android application developers
- to embed native machine code compiled from C and/or C++ source files into
- their application packages.
- IMPORTANT:
- The Android NDK can only be used to target Android system images
- running Cupcake (a.k.a 1.5) or later versions of the platform.
- 1.0 and 1.1 system images are specifically *not* supported due to
- subtle ABI and toolchain changes that happened for the 1.5 release.
- I. Android NDK Goals:
- ---------------------
- The Android VM allows your application's source code to call methods
- implemented in native code through the JNI. In a nutshell, this means that:
- - Your application's source code will declare one or more methods
- with the 'native' keyword to indicate that they are implemented through
- native code. E.g.:
- native byte[] loadFile(String filePath);
- - You must provide a native shared library that contains the
- implementation of these methods, which will be packaged into your
- application's .apk. This library must be named according to standard
- Unix conventions as lib<something>.so, and shall contain a standard JNI
- entry point (more on this later). For example:
- libFileLoader.so
- - Your application must explicitely load the library. For example, to load
- it at application startup, simply add the following to its source code:
- static {
- System.loadLibrary("FileLoader");
- }
- Note that you should not use the 'lib' prefix and '.so' suffix here.
- The Android NDK is a complement to the Android SDK that helps you to:
- - Generate JNI-compatible shared libraries that can run on the Android
- 1.5 platform (and later) running on ARM CPUs.
- - Copy the generated shared libraries to a proper location of your
- application project path, so they will be automatically added to your
- final (and signed) .apks
- - In later revisions of the NDK, we intend to provide tools that help
- debug your native code through a remote gdb connection and as much
- source/symbol information as possible.
- Moreover, the Android NDK provides:
- - A set of cross-toolchains (compilers, linkers, etc..) that can
- generate native ARM binaries on Linux, OS X and Windows (with Cygwin)
- - A set of system headers corresponding to the list of stable native APIs
- supported by the Android platform. This corresponds to definitions that
- are guaranteed to be supported in all later releases of the platform.
- They are documented in the file docs/STABLE-APIS.TXT
- IMPORTANT:
- Keep in mind that most of the native system libraries in Android system
- images are not frozen and might changed drastically, or even deleted,
- in later updates and releases of the platform.
- - A build system that allow developers to only write very short build files
- to describe which sources need to be compiled, and how. The build system
- deals with all the hairy toolchain/platform/CPU/ABI specifics. Moreover,
- later updates of the NDK can add support for more toolchains, platforms,
- system interfaces without requiring changes in the developer's build
- files (more on this later).
- II. Android NDK Non-Goals:
- --------------------------
- The NDK is *not* a good way to write generic native code that runs on Android
- devices. In particular, your applications should still be written in the Java
- programming language, handle Android system events appropriately to avoid the
- "Application Not Responding" dialog or deal with the Android application
- life-cycle.
- Note however that is is possible to write a sophisticated application in
- native code with a small "application wrapper" used to start/stop it
- appropriately.
- A good understanding of JNI is highly recommended, since many operations
- in this environment require specific actions from the developers, that are
- not necessarily common in typical native code. These include:
- - Not being able to directly access the content of VM objects through
- direct native pointers. E.g. you cannot safely get a pointer to a
- String object's 16-bit char array to iterate over it in a loop.
- - Requiring explicit reference management when the native code wants to
- keep handles to VM objects between JNI calls.
- The NDK only provides system headers for a very limited set of native
- APIs and libraries supported by the Android platform. While a typical
- Android system image includes many native shared libraries, these should
- be considered an implementation detail that might change drastically between
- updates and releases of the platform.
- If an Android system library is not explicitely supported by the NDK
- headers, then applications should not depend on it being available, or
- they risk breaking after the next over-the-air system update on various
- devices.
- Selected system libraries will gradually be added to the set of stable NDK
- APIs.
- III. NDK development in practice:
- ---------------------------------
- Here's a very rough overview of how you can develop native code with the
- Android NDK:
- 1/ Run build/host-setup.sh to configure the NDK
- 2/ Place your native sources under $PROJECT/jni/...
- 3/ Write $PROJECT/jni/Android.mk to describe your sources
- to the NDK build system
- 4/ Write apps/<myapp>/Application.mk to describe your application
- and the native sources it needs to the NDK build system
- 5/ Build your native code by running "make APP=<myapp>"
- in the top-level NDK directory.
- The last step will copy, in case of success, the stripped shared libraries
- your application needs to your application's root project directory. You
- will then need to generate your final .apk through the usual means.
- Now, for a few more details:
- III.1/ Configuring the NDK:
- - - - - - - - - - - - - - -
- After installing the NDK as described in docs/INSTALL.TXT, you should call
- the 'build/host-setup.sh' script to configure your NDK.
- This script is used to probe your host system and verify a few pre-requisites.
- It will then generate a configuration file (e.g. out/host/config-host.mk) that
- is later used during NDK builds.
- In some cases, this might instruct you to download an archive containing
- prebuilt toolchain binaries for your development platform, the unzip it
- to the NDK root directory. The message should contain enough information
- to let you do that.
- If you forget this step, trying to build with the NDK will generate an
- error message telling you what to do.
- III.2/ Placing C and C++ sources:
- - - - - - - - - - - - - - - - - -
- You should place your native sources under the following directory:
- $PROJECT/jni/
- Where $PROJECT corresponds to the path of your Android application
- project.
- You are pretty free to organize the content of 'jni' as you want,
- the directory names and structure here will not influence the final
- generated application packages, so you don't have to use pseudo-unique
- names like com.<mycompany>.<myproject> as is the case for application
- package names.
- Note that C and C++ sources are supported. The default C++ file extensions
- supported by the NDK is '.cpp', but other extensions can be handled as well
- (see docs/ANDROID-MK.TXT for details).
- It is possible to store your sources in a different location by adjusting
- your Android.mk file (see below).
- III.3/ Writing an Android.mk build script:
- - - - - - - - - - - - - - - - - - - - - - -
- An Android.mk file is a small build script that you write to describe your
- sources to the NDK build system. Its syntax is described in details in
- the file docs/ANDROID-MK.TXT.
- In a nutshell, the NDK groups your sources into "modules", where each module
- can be one of the following:
- - a static library
- - a shared library
- You can define several modules in a single Android.mk, or you can write
- several Android.mk files, each one defining a single module.
- Note that a single Android.mk might be parsed several times by the build
- system so don't assume that certain variables are not defined in them.
- By default, the NDK will look for the following build script:
- $PROJECT/jni/Android.mk
- If you want to define Android.mk files in sub-directories, you should
- include them explicitely in your top-level Android.mk. There is even
- a helper function to do that, i.e. use:
- include $(call all-subdir-makefiles)
- This will include all Android.mk files in sub-directories of the current
- build file's path.
- III.4/ Writing an Application.mk build file:
- - - - - - - - - - - - - - - - - - - - - - - -
- While an Android.mk file describes your modules to the build system, you
- need to write an Application.mk file to describe your application and the
- modules it requires. This file must be located in:
- $NDK/apps/<myapp>/Application.mk
- Where <myapp> is a short descriptive name for your application that will
- be used to invoke the NDK build (and not go into final APKs). The file is
- used to provide the following to the NDK build:
- - The location of your Android application's project path
- - The list of NDK modules that is required by your application.
- This should really be a list of 'shared library' modules.
- - Optional information, like whether you want a release or debug
- build, specific C or C++ compiler flags and others.
- - Planned: the list of specific platforms/CPUs you want to explicitely
- target (currently only one is supported).
- The syntax of an Application.mk file is very simple and is described in
- docs/APPLICATION-MK.TXT
- You can define several Application.mk corresponding to different builds
- of the same application, for example:
- $NDK/apps/release/Application.mk
- $NDK/apps/debug/Application.mk
- III.5/ Invoke the NDK build system:
- - - - - - - - - - - - - - - - - - -
- On the command-line, go to the top-level NDK directory, then invoke the
- build system with:
- make APP=<myapp>
- Where 'make' refers to GNU Make, and <myapp> is the name of one of the
- subdirectories of '$NDK/apps/'
- This will try to build all modules with relevant options, the final
- shared libraries listed by your Application.mk and, in case of success,
- will copy stripped versions of the shared libraries to your application's
- project path. (Note that unstripped versions are kept for debugging
- purposes, there is no need to copy unstripped binaries to a device).
- IV. Debugging support:
- - - - - - - - - - - - -
- Debugging your native code with this initial release of the NDK is still
- very rough.
- Note that we plan to make this much easier in a later NDK release, all of
- this without changing your sources, Android.mk and Application.mk files.
- =========================
- Android.mk file syntax specification
- Introduction:
- -------------
- This document describes the syntax of Android.mk build file
- written to describe your C and C++ source files to the Android
- NDK. To understand what follows, it is assumed that you have
- read the docs/OVERVIEW.TXT file that explains their role and
- usage.
- Overview:
- ---------
- An Android.mk file is written to describe your sources to the
- build system. More specifically:
- - The file is really a tiny GNU Makefile fragment that will be
- parsed one or more times by the build system. As such, you
- should try to minimize the variables you declare there and
- do not assume that anything is not defined during parsing.
- - The file syntax is designed to allow you to group your
- sources into 'modules'. A module is one of the following:
- - a static library
- - a shared library
- Only shared libraries will be installed/copied to your
- application package. Static libraries can be used to generate
- shared libraries though.
- You can define one or more modules in each Android.mk file,
- and you can use the same source file in several modules.
- - The build system handles many details for you. For example, you
- don't need to list header files or explicit dependencies between
- generated files in your Android.mk. The NDK build system will
- compute these automatically for you.
- This also means that, when updating to newer releases of the NDK,
- you should be able to benefit from new toolchain/platform support
- without having to touch your Android.mk files.
- Note that the syntax is *very* close to the one used in Android.mk files
- distributed with the full open-source Android platform sources. While
- the build system implementation that uses them is different, this is
- an intentional design decision made to allow reuse of 'external' libraries'
- source code easier for application developers.
- Simple example:
- ---------------
- Before describing the syntax in details, let's consider a simple
- "hello world" example, i.e. the following files:
- sources/helloworld/helloworld.c
- sources/helloworld/Android.mk
- Where 'helloworld.c' is the source of a simple JNI shared library
- that implements a native method that returns the "hello world"
- string.
- The corresponding Android.mk file will look like this:
- ---------- cut here ------------------
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE := helloworld
- LOCAL_SRC_FILES := helloworld.c
- include $(BUILD_SHARED_LIBRARY)
- ---------- cut here ------------------
- Now, let's explain these lines:
- LOCAL_PATH := $(call my-dir)
- An Android.mk file must begin with the definition of the LOCAL_PATH variable.
- It is used to locate source files in the development tree. In this example,
- the macro function 'my-dir', provided by the build system, is used to return
- the path of the current directory (i.e. the directory containing the
- Android.mk file itself).
- include $(CLEAR_VARS)
- The CLEAR_VARS variable is provided by the build system and points to a
- special GNU Makefile that will clear many LOCAL_XXX variables for you
- (e.g. LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, etc...),
- with the exception of LOCAL_PATH. This is needed because all build
- control files are parsed in a single GNU Make execution context where
- all variables are global.
- LOCAL_MODULE := helloworld
- The LOCAL_MODULE variable must be defined to identify each module you
- describe in your Android.mk. The name must be *unique* and not contain
- any spaces. Note that the build system will automatically add proper
- prefix and suffix to the corresponding generated file. In other words,
- a shared library module named 'foo' will generate 'libfoo.so'.
- IMPORTANT NOTE:
- If you name your module 'libfoo', the build system will not
- add another 'lib' prefix and will generate libfoo.so as well.
- This is to support Android.mk files that originate from the
- Android platform sources, would you need to use these.
- LOCAL_SRC_FILES := helloworld.c
- The LOCAL_SRC_FILES variables must contain a list of C and/or C++ source
- files that will be built and assemble into a module. Note that you should
- not list header and included files here, because the build system will
- compute dependencies automatically for you; just list the source files
- that will be passed directly to a compiler, and you should be good.
- Note that the default extension for C++ source files is '.cpp'. It is
- however possible to specify a different one by defining the variable
- LOCAL_DEFAULT_CPP_EXTENSION. Don't forget the initial dot (i.e. '.cxx'
- will work, but not 'cxx').
- include $(BUILD_SHARED_LIBRARY)
- The BUILD_SHARED_LIBRARY is a variable provided by the build system that
- points to a GNU Makefile script that is in charge of collecting all the
- information you defined in LOCAL_XXX variables since the latest
- 'include $(CLEAR_VARS)' and determine what to build, and how to do it
- exactly. There is also BUILD_STATIC_LIBRARY to generate a static library.
- There are more complex examples under sources/samples, with commented
- Android.mk files that you can look at.
- Reference:
- ----------
- This is the list of variables you should either rely on or define in
- an Android.mk. You can define other variables for your own usage, but
- the NDK build system reserves the following variable names:
- - names that begin with LOCAL_ (e.g. LOCAL_MODULE)
- - names that begin with PRIVATE_, NDK_ or APP_ (used internally)
- - lower-case names (used internally, e.g. 'my-dir')
- If you need to define your own convenience variables in an Android.mk
- file, we recommend using the MY_ prefix, for a trivial example:
- ---------- cut here ------------------
- MY_SOURCES := foo.c
- ifneq ($(MY_CONFIG_BAR),)
- MY_SOURCES += bar.c
- endif
- LOCAL_SRC_FILES += $(MY_SOURCES)
- ---------- cut here ------------------
- So, here we go:
- NDK-provided variables:
- - - - - - - - - - - - -
- These GNU Make variables are defined by the build system before
- your Android.mk file is parsed. Note that under certain circumstances
- the NDK might parse your Android.mk several times, each with different
- definition for some of these variables.
- CLEAR_VARS
- Points to a build script that undefines nearly all LOCAL_XXX variables
- listed in the "Module-description" section below. You must include
- the script before starting a new module, e.g.:
- include $(CLEAR_VARS)
- BUILD_SHARED_LIBRARY
- Points to a build script that collects all the information about the
- module you provided in LOCAL_XXX variables and determines how to build
- a target shared library from the sources you listed. Note that you
- must have LOCAL_MODULE and LOCAL_SRC_FILES defined, at a minimum before
- including this file. Example usage:
- include $(BUILD_SHARED_LIBRARY)
- note that this will generate a file named lib$(LOCAL_MODULE).so
- BUILD_STATIC_LIBRARY
- A variant of BUILD_SHARED_LIBRARY that is used to build a target static
- library instead. Static libraries are not copied into your
- project/packages but can be used to build shared libraries (see
- LOCAL_STATIC_LIBRARIES and LOCAL_STATIC_WHOLE_LIBRARIES described below).
- Example usage:
- include $(BUILD_STATIC_LIBRARY)
- Note that this will generate a file named lib$(LOCAL_MODULE).a
- TARGET_ARCH
- Name of the target CPU architecture as it is specified by the
- full Android open-source build. This is 'arm' for any ARM-compatible
- build, independent of the CPU architecture revision.
- TARGET_PLATFORM
- Name of the target Android platform when this Android.mk is parsed.
- For now, only 'android-1.5' is supported.
- TARGET_ARCH_ABI
- Name of the target CPU+ABI when this Android.mk is parsed.
- For now, only 'arm' is supported, which really means the following:
- ARMv5TE or higher CPU, with 'softfloat' floating point support
- Other target ABIs will be introduced in future releases of the NDK
- and will have a different name. Note that all ARM-based ABIs will
- have 'TARGET_ARCH' defined to 'arm', but may have different
- 'TARGET_ARCH_ABI'
- TARGET_ABI
- The concatenation of target platform and abi, it really is defined
- as $(TARGET_PLATFORM)-$(TARGET_ARCH_ABI) and is useful when you want
- to test against a specific target system image for a real device.
- By default, this will be 'android-1.5-arm'
- NDK-provided function macros:
- - - - - - - - - - - - - - - -
- The following are GNU Make 'function' macros, and must be evaluated
- by using '$(call <function>)'. They return textual information.
- my-dir
- Returns the path of the current Android.mk's directory, relative
- to the top of the NDK build system. This is useful to define
- LOCAL_PATH at the start of your Android.mk as with:
- LOCAL_PATH := $(call my-dir)
- all-subdir-makefiles
- Returns a list of Android.mk located in all sub-directories of
- the current 'my-dir' path. For example, consider the following
- hierarchy:
- sources/foo/Android.mk
- sources/foo/lib1/Android.mk
- sources/foo/lib2/Android.mk
- If sources/foo/Android.mk contains the single line:
- include $(call all-subdir-makefiles)
- Then it will include automatically sources/foo/lib1/Android.mk and
- sources/foo/lib2/Android.mk
- This function can be used to provide deep-nested source directory
- hierarchies to the build system. Note that by default, the NDK
- will only look for files in sources/*/Android.mk
- this-makefile
- Returns the path of the current Makefile (i.e. where the function
- is called).
- parent-makefile
- Returns the path of the parent Makefile in the inclusion tree,
- i.e. the path of the Makefile that included the current one.
- grand-parent-makefile
- Guess what...
- Module-description variables:
- - - - - - - - - - - - - - - -
- The following variables are used to describe your module to the build
- system. You should define some of them between an 'include $(CLEAR_VARS)'
- and an 'include $(BUILD_XXXXX)'. As written previously, $(CLEAR_VARS) is
- a script that will undefine/clear all of these variables, unless explicitely
- noted in their description.
- LOCAL_PATH
- This variable is used to give the path of the current file.
- You MUST define it at the start of your Android.mk, which can
- be done with:
- LOCAL_PATH := $(call my-dir)
- This variable is *not* cleared by $(CLEAR_VARS) so only one
- definition per Android.mk is needed (in case you define several
- modules in a single file).
- LOCAL_MODULE
- This is the name of your module. It must be unique among all
- module names, and shall not contain any space. You MUST define
- it before including any $(BUILD_XXXX) script.
- The module name determines the name of generated files, e.g.
- lib<foo>.so for a shared library module named <foo>. However
- you should only refer to other modules with their 'normal'
- name (e.g. <foo>) in your NDK build files (either Android.mk
- or Application.mk)
- LOCAL_SRC_FILES
- This is a list of source files that will be built for your module.
- Only list the files that will be passed to a compiler, since the
- build system automatically computes dependencies for you.
- Note that source files names are all relative to LOCAL_PATH and
- you can use path components, e.g.:
- LOCAL_SRC_FILES := foo.c \
- toto/bar.c
- NOTE: Always use Unix-style forward slashes (/) in build files.
- Windows-style back-slashes will not be handled properly.
- LOCAL_CPP_EXTENSION
- This is an optional variable that can be defined to indicate
- the file extension of C++ source files. The default is '.cpp'
- but you can change it. For example:
- LOCAL_CPP_EXTENSION := .cxx
- LOCAL_CFLAGS
- An optional set of compiler flags that will be passed when building
- C source files (*not* C++ sources).
- This can be useful to specify an additionnal include path
- (relative to the top of the NDK directory), macro definitions
- or compile options.
- IMPORTANT: Try not to change the optimization/debugging level in
- your Android.mk, this can be handled automatically for
- you by specifying the appropriate information in
- your Application.mk, and will let the NDK generate
- useful data files used during debugging.
- LOCAL_CXXFLAGS
- Same as LOCAL_CFLAGS for C++ source files
- LOCAL_CPPFLAGS
- Same as LOCAL_CFLAGS but used for both C and C++ source files
- LOCAL_STATIC_LIBRARIES
- The list of static libraries modules (built with BUILD_STATIC_LIBRARY)
- that should be linked to this module. This only makes sense in
- shared library modules.
- LOCAL_SHARED_LIBRARIES
- The list of shared libraries *modules* this module depends on at runtime.
- This is necessary at link time and to embed the corresponding information
- in the generated file.
- Note that this does not append the listed modules to the build graph,
- i.e. you should still add them to your application's required modules
- in your Application.mk
- ===================
- Application.mk file syntax specification
-
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
TheApplication.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
ordebug
. 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 todebug
instead ofrelease
. Override this default value by settingAPP_OPTIM
torelease
.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.mkTo specify in
foo/Android.mk
that you want to add the path to thebar
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, useAPP_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 namedAndroid.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 useAPP_ABI
to select a different ABI. Table 1 shows theAPP_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. UseAPP_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
inApplication.mk
for your whole project. For more information, see the documentation for this variable onAndroid.mk
.NDK_TOOLCHAIN_VERSION
Define this variable as either
4.9
or4.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 asclang3.4
,clang3.5
, orclang
. Specifyingclang
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 totrue
if your project targetsandroid-16
or higher. You may set it manually to eithertrue
orfalse
.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 theAndroid.mk
file for all static library modules in this project. For more information, see the documentation forLOCAL_THIN_ARCHIVE
onAndroid.mk
. - 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++。
这已得到纠正,以建立完整相匹配的Android系统。
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> -
=================================
-
NDK提供的共享库(Prebuilt)
-
Android NDK r5 开始支持预编译库(动态库和静态库),即程序能使用库的预编译版本。
该特性可用于以下两方面:
1)向第三方NDK开发人员发布你的共享库而不用提供源码。
2)使用一个提前编译好的库(预编译库)来加速编译过程。
本文说明该特性如何工作。
I. 声明一个预编译库的模块
对于Android编译工具而言,每个预编译库必须声明为一个独立的模块。这里举一个例子,假设 libfoo.so 文件与 Android.mk 位于同一个目录:
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE := foo-prebuilt
- LOCAL_SRC_FILES := libfoo.so
- 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的简单例子如下:
- include $(CLEAR_VARS)
- LOCAL_MODULE := foo-user
- LOCAL_SRC_FILES := foo-user.c
- LOCAL_SHARED_LIBRARIES := foo-prebuilt
- include $(BUILD_SHARED_LIBRARY)
III. 将预编译库的头文件导出
得到预编译库之后,一般需要它对应的头文件。例如前面的libfoo.so,它有对应的foo.h。编译依赖libfoo.so的模块时,需要将该 头文件和它的路径提供给NDK编译系统。一种简单方法是,前面在定义该预编译库的时候,使用LOCAL_EXPORT_C_INCLUDES 变量。例如,假设文件 foo.h 位于当前预编译模块所在目录的 include 子目录,则可以在预编译模块的Android.mk文件中编写如下:
- include $(CLEAR_VARS)
- LOCAL_MODULE := foo-prebuilt
- LOCAL_SRC_FILES := libfoo.so
- LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
- include $(PREBUILT_SHARED_LIBRARY)
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:
- include $(CLEAR_VARS)
- LOCAL_MODULE := foo-prebuilt
- LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfoo.so
- LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
- 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的兼容,但是反过来就不行。
支付宝扫一扫捐赠
微信公众号: 共鸣圈
欢迎讨论,邮件: 924948$qq.com 请把$改成@
QQ群:263132197
QQ: 924948