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.mkbuild 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.mkfile is really a tiny GNU Makefile fragment that defines several variables for compilation. It usually resides under$PROJECT/jni/, where$PROJECTpoints 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.mkHere,
<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.mkfile 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
releaseordebug. 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:debuggablein your application manifest's<application>tag will cause this variable to default todebuginstead ofrelease. Override this default value by settingAPP_OPTIMtorelease.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.mkfile 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.mkthat you want to add the path to thebarsources during compilation, you should use:APP_CFLAGS += -Isources/barOr, alternatively:
APP_CFLAGS += -I$(LOCAL_PATH)/../bar-I../barwill 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_CFLAGSmatches 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_CPPFLAGSnow 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_SCRIPTto 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
armeabiABI. This machine code corresponds to an ARMv5TE-based CPU with software floating point operations. You can useAPP_ABIto select a different ABI. Table 1 shows theAPP_ABIsettings for different instruction sets.Table 1.
APP_ABIsettings for different instruction sets.Instruction set Value Hardware FPU instructions on ARMv7 based devices APP_ABI := armeabi-v7aARMv8 AArch64 APP_ABI := arm64-v8aIA-32 APP_ABI := x86Intel64 APP_ABI := x86_64MIPS32 APP_ABI := mipsMIPS64 (r6) APP_ABI := mips64All supported instruction sets APP_ABI := allNote:
allis 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 mipsFor 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-3specifies 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_STLto 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_COMMANDSinApplication.mkfor your whole project. For more information, see the documentation for this variable onAndroid.mk.NDK_TOOLCHAIN_VERSION
Define this variable as either
4.9or4.8to 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. Specifyingclangchooses 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
-fPIEflag. This flag makes it harder to exploit memory corruption bugs by randomizing code location. By default,ndk-buildautomatically sets this value totrueif your project targetsandroid-16or higher. You may set it manually to eithertrueorfalse.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_ARCHIVEin theAndroid.mkfile for all static library modules in this project. For more information, see the documentation forLOCAL_THIN_ARCHIVEonAndroid.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文件中編寫如下:
這個 LOCAL_EXPORT_C_INCLUDES 定義確保了任何依賴這個預編譯庫的模塊會自動在自己的 LOCAL_C_INCLUDES 變量中增加到這個預編譯庫的include目錄的路徑,從而能夠找到其中的頭文件。- 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的兼容,但是反過來就不行。
