Brief introduction
Android.mk mainly describes how C or C + + files are used in the NDK project, which mainly describes the building rules of ANDROID.MK
Overview
- The Android.mk file describes how your source code is built, mainly including: The file is actually a simplified GNU makefile file. The file is parsed one or more times by the build system, so you need to customize the variables as little as possible. Similarly, there is no way to think that no variables are defined during parsing
- This file syntax determines how your source code is organized into modules, and the concept of "module" is:
The compiler simply installs/copies the dynamic library into your APK package. In addition, static libraries can generate dynamic libraries
You can define one or more modules in each android.mk file, and you can share one source file in multiple modules
- The compiler automatically adds more detailed information, such as no need to list the included header files or the relationship that does not require a very explicit file, and the NDK compiler has calculated for you automatically.
Similarly, when you update to the newly released NDK, you do not need to modify the Android.mk file to automatically compile with the new tool chain/platform.
Note that this syntax is very close to the ANDRIOD.MK syntax in the full Android open source project, but the compiler executes in a different way. To make it easier for developers to reuse the source files that compile the underlying library, they are intentionally designed to be similar in format.
Simple example
Before describing the syntax in detail, it is necessary to consider the android.mk in Hello_jni
----------cut here------------------ Local_path:= $ (call My-dir) include $ (clear_vars) local_module := Hello-jni Local_src_files:= hello-jni.c include $ (build_shared_library) ----------cut here--------------- ---
Now, carefully analyze the meaning of each line
Local_path: = $ (call My-dir)
A android.ml file must begin with the definition of the Local_path variable, which is used primarily to locate the source location. In this example, the macro definition "My-dir" is provided by the compiler, which returns the current folder path (the folder that contains the ANDROID.MK)
Include $ (clear_vars)
The clear_vars variable is defined by the compiler, which specifies a special GNU makefile file that clears local_xxx variables other than Local_path (for example, Local_module,local_src_files, Local_static_libraries, etc.). All the build control files are parsed into a GNU build run context, where all the variables are global, so the variable is valuable.
Local_module: = Hello-jni
The Local_module variable is used to define all the module names that need to be defined. The module name must be unique and cannot contain spaces. Note The compiler adds a prefix and suffix to the generated module name. For example, a module called ' foo ' will generate ' libfoo.so '
Note: If you define a module named "Libfoo", the compiler does not add the ' lib ' prefix again, and it also generates ' libfoo.so '.
Local_src_files: = Hello-jni.c
The Local_src_files variable contains all the C + + source files required to build the module. Because the compiler automatically calculates the relationship since the file, there is no need to add a header file here, just list all the source files directly.
Note the suffix of the default C + + file is ". cpp". You can use the Local_cpp_extension variable to modify the suffix used by C + + files, and be sure to add "." (correct: '. Cxx ', error: ' Cxx ').
Include $ (build_shared_library)
Build_shared_library is a system variable that points to the GNU Makefile script, which collects all the information defined in LOCAL_XXX and decides on the goals to be built and how to build it. Use Build_static__library to generate a static library.
You can view more complex android.mk files in the NDK's sample directory.
Reference
Some of the variables listed below are completely reliable in android.mk. You can define some variables yourself, but the NDK compiler retains these keywords:
- Beginning with "Local_" (Example: Local_home)
- Starting with "Private_", "NDK", "app_" (internal use)
- Lowercase variable name (internal use, example: My-dir)
If you need to customize variables, we recommend using "My_" as a prefix, for example:
----------cut here------------------ My_sources:= foo.c ifneq ($ (My_config_bar),) my_sources += bar.c endif Local_src_files += $ (my_sources)----------cut here------------------
Variables provided by NDK
These GNU make variables have been defined before the Android.mk file is parsed. Note In some cases, the NDK may parse android.mk several times under the definition of a different GNU make variable
Clear_vars
指向清除大部分定义在”Module-description”节下LOCAL_XXX变量的构建脚本。它必须包含在开始说明一个新模块之前,使用实例:
Include $ (clear_vars)
Build_shared_library
指向收集所有LOCAL_XXX变量提供的信息并且决定如何由源码文件构建动态库的脚本文件。注意在使用该变量之前必须定义LOCAL_MODULE和LOCAL_SRC_FILE。使用说明:
Include $ (build_shared_library)
This generates a plain text libxxx.so file.
Build_static_library
Build_shared_library is a VARIANT that generates a static library. The static library will not be copied/packaged into the APK package file, but we can use it to generate a dynamic library (refer to the descriptions of local_static_library and local_whole_static_library below). Instructions for use:
Include $ (build_static_library)
Prebuilt_shared_library
A build script that points to a precompiled dynamic library. Unlike Build_shared_library and Build_static_library, Local_src_files can only be a path to a precompiled dynamic library rather than a source file (for example: foo/libfoo.so).
You can use the Local_prebuilts variable in other modules to reference the precompiled Library (refer to NDK prebuilt Library support for details)
Prebuilt_static_librar
is similar to prebuilt_shared_library, but specifies a static library.
Target_arch
The name of the target CPU architecture, for all arm-compatible compilers, the target architecture is arm, and the independent CPU architecture will be different
Target_platform
The name of the target Android platform. For example android-3 corresponds to Android 1.5
Target_arch_abi
Name of the target CPU and ABI, you can specify one or more of the following values
Armeabi For ARMv5TE armeabi-v7a for ARMv7 arm64-v8a for ARMv8 AArch64 x86 for i686 x86_64 For x86- -mips32 (R1) mips64 for mips64 (R6)
Note: This variable is defined as ' arm ' until the Android NDK 1.6_r1. However, this value is redefined internally when used as a value that is more matched to the Android platform.
Target_abi
The link between the target platform and the ABI, which is actually defined as a "-" connection, will be useful in testing the physical machine with the specified system files.
The default value is "Android-3-armeabi"
Functions provided by the NDK
is a "function" macro in GNU make and must be called in "$ (call <function>)" mode. Returns the return value of the text.
My-dir
Returns the last contained makefile path, typically the current android.mk path. It is usually used in android.mk header files to fix Local_path:
Local_path: = $ (call My-dir)
tip : Based on how GNU make works, he actually returns the last contained makefile file path. Do not include any other files after calling My-dir, for example, consider the following example.
Local_path: = $ (call My-dir) ... declare one module include $ (local_path)/foo/' android.mk ' local_path := $ (call My-dir) ... declare another module
Because the include file was my-dir to $path/foo before the second call to My-dir, the second call to My-dir would define Local_path as $path/foo instead of $path. Therefore, it is best to put the action containing the file after all content, for example:
Local_path: = $ (call My-dir) ... declare one module local_path:= $ (call My-dir) ... declare a nother Module # Extra includes at the end of the ' Android.mk ' include $ (local_path)/foo/' android.mk '
If this is inconvenient, save the path of My-dir to a custom variable, for example
My_local_path: = $ (call My-dir) Local_path:= $ (my_local_path) ... declare one module include $ (Local_path)/foo/' android.mk ' local_path:= $ (my_local_path) ... declare another module
All-subdir-makefiles
Returns the path to all the "android.mk" files in the subdirectory of the current ' my-dir ' directory, assuming the following files
Sources/foo/android.mksources/foo/lib1/android.mksources/foo/lib2/android.mk
If SOURCE/FOO/ANDROID.MK contains the following code
Include $ (call All-subdir-makefiles)
Then it will automatically include sources/foo/lib1/ Android.mk and sources/foo/lib2/.Android.mk
该功能通常在有多层源码目录的工程中使用。注意,NDK只会查找sources/*/Android.mk
This-makefile
Returns the current Makefile directory (the function is called the makefile)
Parent-makefile
Returns the parent makefile file of the makefile in the containing tree. Contains the current makefile file
Grand-parent-makefile
Guess what this is.
Import-module
Contains the android.mk of another module by name. A typical example:
$ (call import-module,<name>)
It finds the module by looking for the current set of Ndk_module_path environment variables, automatically including the module's ANDROID.MK file
Variables described by the module
The following variables are used to describe custom modules in the compilation system. You can include them in two more ' include '. As previously written, a script will clean up all of them unless you explicitly indicate them.
Local_path
This variable is used to obtain the current path and must be defined at the beginning of the Android.mk file, for example:
Local_path: = $ (call My-dir)
The variable is not cleaned, so it needs to be defined only once (perhaps you will define multiple modules in a file)
Local_module
The name of the current module. Its name must be unique and cannot contain spaces. Need to be defined before any script. The module name defaults to the name of the generated file, such as Lib<foo>.so is a <foo> generated dynamic library file. But you only need to use "normal" names (such as <foo>) in other files in the NDK compilation system, such as ANDROID.MK or application.mk
Local_module_filename
The variable is optional and allows you to rename the name of the generated file. The block name defaults to the name of the generated file, such as Lib<foo>.so is a <foo> generated dynamic library file.
You can change by defining local_module_filename, for example:
Local_module: = foo-version-1local_module_filename:= Libfoo
Note: You cannot define the path or suffix of a file to Local_module_filename, which is automatically added by the compilation system.
Local_src_files
Lists the source code required for all compiled modules. Until the compiler calculates a dependency, only the files listed will participate in the compilation.
Note: All files are in the Local_path directory, and you can add files from subdirectories. For example:
Local_src_files: = foo.c toto/bar.c
You can also use an absolute path. For example:
Local_src_files: =/home/user/mysources/foo.c
Windows platform:
Local_src_files: = c:/users/user/sources/foo.c
In order for the development environment to be better ported, it is best not to use absolute paths
Note: Unix style typically uses a slash (/) as the path delimiter. Windows-style backslashes are not necessarily well supported.
Local_cpp_extension
The suffix name for the custom C + + file. Must be in "." At the beginning, the default suffix is "cpp", for example:
Local_cpp_extension: =. cxx
After NDK R7, you can define multiple suffix names:
Local_cpp_extension: =. cxx. CPP. cc
Local_cpp_features
The optional variable can specify a specific C + + attribute. If your code uses the Rtti attribute, you can define:
Local_cpp_features: = Rtti
The display code uses exception handling:
Local_cpp_features: = Exceptions
Multiple attributes can be defined at the same time (order independent)
Local_cpp_features: = Rtti FEATURES
The variable can be correctly set to compile/link flags when compiling the module. The variable can be guaranteed to be properly chained to a binary file.
It is recommended to use this variable instead of directly defining-frtti and-fexceptions in Local_cppflags
Local_c_includes
An optional variable that contains the path to the file, which is added to the Include directory at compile time, for example:
Local_c_includes: = Sources/foo
Even this is possible:
Local_c_includes: = $ (Local_path)/. /foo
These definitions are placed before the Local_cflags/local_cppflags
The Local_c_include path is also used for automatic ndk-gdb debugging.
LOCAL_CFLAGS
可选的编译标识,也可以用来添加额外的宏定义或者编译选项。
重要:不要修改任何Android.mk中的优化、调试级别,这些会在指定Andorid.mk文件中的目标信息时自动化处理,ndk也会在调试时自动生成调试文件。
注意:在android-ndk-1.5_r1中,只在C源代码中产生作用(现在可以使用LOCAL_CPPFLAG来指定编译选项)。
可以使用LOCAL_CFLAGS+=-I<path>来指定附加包含目录。由于ndk-gdb会使用该路径,最好使用LOCAL_C_INCLUDES来实现该功能。
Local_cxxflags
LOCAL_CPPFLAG的别名,注意该变量可能在未来的NDK版本中被抛弃。
Local_cppflags
在编译C++源码时的一个可选编译选项的变量。该变量会出现在LOCAL_CFLAGS之后
注意:在android-ndk-1.5-r1中,该变量适用于C和C++格式的源码。(现在也可以使用LOCAL_CFLAGS来指定所有C/C++源码编译选项)
Local_static_libraries
Lists the static libraries that have been made since all current modules.
If the current module is a dynamic library or a running file, these static libraries are forced to connect to the generated binaries.
If the current file is a static library, only the other modules will be notified that the module will rely on these listed static libraries
Local_shared_libraries
Lists the dynamic libraries that the module relies on at run time. He will embed some information about these dynamic libraries when linking, so this information is necessary.
Local_whole_static_libraries
A variant of local_static_libraries that is used to express that the corresponding binary module should be connected as a "complete file".
Local_ldlibs
Some other link options when creating a dynamic library or when you can run a file. For example, when Ld.gold is default, the LD.BFD linker link is used under arm/x86 GCC 4.6+
Local_ldflags + =-FUSE-LD=BFD
Note: This option is ignored when compiling a static library, and the NDK emits a warning message when you define the variable
Local_allow_undefined_symbols
By default, when an undefined symbol is referenced in a dynamic library, a "undefined symbol" error is generated. This will help you find errors in the source code.
However, if for some reason you need to disable this check, set this value to ' true '. Note the generated binaries may fail at run time.
Note: This option is ignored when compiling a static library, and the NDK emits a warning message when you define the variable
Local_arm_mode
By default, ARM's target program's instructions are ' thumb ' mode, the instruction length in ' thumb ' mode is 16 bits, and the Thumb STL library is linked. You can use this variable to generate an ' arm ' directive. The directive is 32-bit. Usage examples:
Local_arm_mode: = ARM
Note: You can specify the '. Arm ' suffix source to generate assembly instructions in arm format, for example:
Local_src_files: = foo.c bar.c.arm
Tells the compiler to always compile bar into ARM instruction format, while the type of foo.c is determined by Local_arm_mode.
Note: After setting App_optim as ' Debug ' in Android.mk, an arm format file is also generated. This is due to the fact that the debugging tools in the tool chain do not handle the thumb instructions well.
Local_arm_neon
When the variable is defined, the c/c++/assembly code is allowed to use neon technology.
Can only be defined when using "armeabi-v7a" based on the ARMv7 instruction set. Note that not all ARMV7 series CPUs support the neon extension instruction set.
In addition, you can specify that the file is compiled with the neon instruction set by adding the '. Neon ' suffix.
Local_src_files = Foo.c.neon bar.c Zoo.c.arm.neon
In this example, ' FOO.C ' will be compiled into Thumb+neon mode, ' BAR.C ' will be compiled into thumb mode. ZOO.C will be compiled into Arm+neon mode
Note: If you want to use it at the same time, the '. Neon ' suffix must appear after the '. Arm ' suffix.
Local_disable_no_execute
Android NDK R4 adds support for the "NX bit" security feature. It is turned on by default and can be turned off by setting the value to ' true '.
Local_disable_relro
By default, the NDK compiled code is built with read-only relocations and GOT protection. This instructs the runtime linker to mark certain regions of memory as being read-only after relocation, making certain SE Curity exploits (such as GOT overwrites) harder to perform.
It is enabled by default, but can disable it if you really need-to-setting this variable to ' true .
Note:these protections is only effective on newer Android devices ("Jelly Bean" and beyond). The code would still run on older versions (albeit without memory protections).
Reference http://blog.chinaunix.net/uid-24203478-id-3298210.html
Local_disable_format_string_checks
By default, the NDK compiled code is compiled with format string protection. This forces a compiler error if a non-constant format string was used in a printf style function.
It is enabled by default, but can disable it if you really need-to-setting this variable to ' true .
Local_export_cflags
This variable will record the C + + compilation options set in the current module. When other modules refer to the module using Local_static_libraries or Local_shared_libraries, Local_cflags will automatically add the C + + compilation options set above.
include $ (clear_vars) Local_module:= foolocal_src_files:= foo/foo.clocal_export_cflags: =-dfoo=1include $ (build_static_library)
Other module definitions
include $ (clear_vars) Local_module:= barlocal_src_files:= bar.clocal_cflags:=-dbar=2 local_static_libraries:= fooinclude $ (build_shared_library)
In this way, the compiler identifier for the following module will be set to ' -DFOO=1 -DBAR=2
The export identity is internally represented as local_cflags, so it can be easily used. This feature can be passed: For example ' Zoo ' relies on ' bar ', and ' bar ' depends on ' foo ', then ' Zoo ' will inherit ' foo ' export symbol.
LOCAL_EXPORT_CPPFLAGS
和LOCAL_EXPORT_CFLAGS类似,但是仅仅包含C++标识。
Local_export_c_includes
Similar to Local_export_cflags, but only used to contain the C header file path. Used when ' bar.c ' needs to include the header file provided by ' Foo '
Local_export_ldflags
Similar to Local_export_cflags, but used to handle link symbols.
Local_export_ldlibs
Similar to Local_export_cflags, a specified system library prefixed with '-l ' is usually set. Because of how the UNIX compiler works, the imported link identity is added to the local_ldlibs of the module.
When ' foo ' needs to be compiled into a static library and it has some code that relies on the system library, you can use Local_export_ldlibs to derive dependencies. For example:
include $ (clear_vars) Local_module:= foolocal_src_files:= foo/foo.clocal_export_ldlibs: = -lloginclude $ (build_static_library) include $ (clear_vars) Local_module:= barlocal_src_files:= bar.clocal_static_libraries:= fooinclude $ (build_shared_library)
Because it relies on ' foo ', libbar.so compile will add the-llog option at the end of the link command to show that it relies on the system's log library
Local_short_commands
When the module is generated by many source files or relies on static or dynamic libraries when set to ' true ', he forces the compilation system to use internal list files, and uses a binary compressed file or statically linked to the @ syntax.
This is useful in Windows systems where the command line receives up to 8,191 bytes, which is far from enough for a complex project.
This affects every individual file, with almost all the compiled identifiers in each of the internally listed files.
Local_thin_archive
Set to ' true ' when compiling the static library. He will generate a simple archive file. For example, a library file (LIBFOO.A) does not contain any object files and contains only the path to the file where it should contain the object.
He is often used to reduce the volume of compiled output. The disadvantage is that these contained library files cannot be moved to other paths (all paths are internally dependent).
The valid value is ' true ', ' false ' or null. Default values can be set by app_thin_archive.
Note: This command is ignored in non-static libraries or precompiled static libraries.
Local_filter_asm
Define the variable on the command line to filter the assembly files that are defined or generated from the local_src_files.
When it is defined, the following things will happen:
- Some C or C + + source files are generated into a temporary assembly file (rather than compiled into an object file)
- Some temporary assembly files, and the assembly files listed in Local_src_files, are sent to the LOCAL_FILTER_ASM command to generate additional assembly files
- Filtered assembly file to generate object file
In other words, if you define:
Local_src_files : = foo.c bar. S local_filter_asm:= myasmfilter foo.c--1--> $OBJS _dir/foo. S.original--2-$OBJS _dir/foo. s--3 --$OBJS _dir/foo.o bar. S --2--and$OBJS _dir/bar. s--3--> $OBJS _dir/bar.o
"1" corresponds to the compiler, "2" corresponds to the filter, "3" corresponds to the assembler. The filter is the first input file as its first parameter of the command, and the output file name is its second parameter.
Myasmfilter $OBJS _dir/foo. S.original$objs_dir/foo. S Myasmfilter Bar. S $OBJS _dir/bar. S
Introduction to NDK configuration file android.mk