Android ndk Development Guide --- application. mk File
Http://www.iteye.com/topic/1113483
Application. mk File
Introduction:
-----------------------------
To compile C \ c ++ code into a so file, you still need an application. mk file.
This document describes how to use the application. mk syntax of the local module required by your android application.
Application. mk is used to describe the modules required in your application (static or dynamic library ).
The application. mk file is usually placed under $ Project/JNI/application. mk. $ project refers to your project.
Another method is to place it in the subdirectory at the top level:
$ Ndk/apps directory, for example:
$ Ndk/apps/<MyApp>/application. mk
<MyApp> is short for describing the application of your ndk compilation system (this name does not generate a shared library or the final package)
The following are the variables defined in application. mk.
App_project_path
This variable is mandatory and gives an absolute path to the root directory of the application project. This is used to copy or install a JNI library without any version restrictions, so as to provide a detailed path for the APK generation tool.
App_modules
This variable is optional. If not defined, ndk is compiled by the default module declared in Android. mk and contains all the sub-files (makefile files)
If app_modules is defined, it cannot be a list of modules separated by spaces. The module name is defined in local_module In the Android. mk file. Note that the ndk automatically calculates the module dependency.
Note: ndk changes the behavior of this variable in R4. Before the change:
-In your application. mk, this variable is mandatory.
-All required modules must be explicitly listed.
App_optim
This variable is optional and is used to define "release" or "debug ". When compiling your application module, it can be used to change the priority.
The "release" mode is default and highly optimized binary code is generated. The "debug" Mode generates unoptimized binary code, but many bugs can be detected and used for debugging.
NOTE: If your application is debuggable (that is, if Android: debuggable is set to "true" in your configuration file "). The default value is "debug" rather than "release ". This can be overwritten by setting app_optim to "release.
Note: Debugging can be performed in the "release" and "debug" modes. However, after compiling in the "release" mode, fewer bug information is provided. When we know the bug, some variables are optimized or cannot be detected at all. The code re-sorting will make these variables more difficult to read, and make these tracks more unreliable.
App_cflags
When the compilation module contains any c file or C ++ file, the C compiler signal is sent. Here, you can adjust the Compilation When you need these modules in your application. In this way, you are not allowed to directly change Android. mk to the file itself.
Important warning: ++ ++
+
+ In these compilation, all paths must correspond to the top-level ndk directory.
+ For example, if you have the following settings:
+
+ Sources/Foo/Android. mk
+ Sources/BAR/Android. mk
+ During compilation, to specify the path you want to add to the bar source code in Foo/Android. mk,
+ You should use
+ App_cflags + =-isources/Bar
+ Or alternate:
+ App_cflags + =-I $ (local_path)/../Bar
+
+ Using '-l ../BAR/' won't work, thinking it will be equivalent to "-L $ ndk_root/../Bar"
++ ++
Note: Android ndk 1.5_r1 only applies to C source files, not c ++.
This has been corrected to build a completely matched Android system.
App_cxxflags
App_cppflags alias, which has been considered to be removed in future versions
App_cppflags
When only the C ++ source file is compiled, you can use this c ++ compiler to set
Note: In the android NDK-1.5_r1, this flag can be applied to C and C ++ source files. In addition, it is corrected to build a complete Android compilation system that matches the system. You can also use app_cflags to apply it to C or C ++ source files.
App_cflags is recommended.
App_build_script
By default, the ndk compilation system searches for the Android. mk file in the $ (app_project_path)/JNI directory:
$ (App_project_path)/JNI/Android. mk
If you want to override this behavior, you can define app_build_script to specify a backup compilation script. A non-absolute path is always interpreted as the top-level directory relative to the ndk.
App_abi
By default, the ndk compilation system evict "armeabi" Abi to generate machine code. Which is equivalent to an armv5te that can be used for floating-point operations based on the CPU. You can use app_abi to select a different Abi.
For example, to support hardware FPU commands on armv7 devices. Available
App_abi: = armeabi-v7a
Or to support the IA-32 instruction set, you can use
App_abi: = x86
Or you can use
App_abi: = armeabi armeabi-v7a x86
App_stl
By default, the ndk compilation system provides C ++ header files for the minimum C ++ Runtime Library (/system/lib/libstdc ++. So.
However, the implementation of ndk C ++ allows you to use or link to your own applications.
For example:
App_stl: = stlport_static --> static stlport Library
App_stl: = stlport_shared --> shared stlport Library
App_stl: = System --> default C ++ Runtime Library
The following is an example of an application. mk file:
App_project_path: = <path to project>
**************************************** **************************************** **************************************** *********************
Android ndk Development Guide --- Android. mk File
Http://www.iteye.com/topic/1113090
Android. mk File Syntax details
Introduction:
------------
This document describes the syntax of the android. mk compilation file in your C or C ++ source file. To understand them, you need to read it first.
Docs/overview.html (http://hualang.iteye.com/blog/1135105) file to understand its role
Overview:
------------
The android. mk file is used to describe the build system (compilation system). More accurately:
-- This file is a micro GNU makefile segment, which is parsed once or multiple times by the build system. In this way, you can minimize the variables you declare and do not think that there is no definition in the parsing process.
-- The syntax of this file is used to allow you to organize the source file into a module. This module contains:
-A static library (. A file)
-A dynamic library (. So file)
Only the dynamic library will be installed/copied to your application package, although the static library can be used to generate a dynamic library. You can define an android. mk file in each module. You can also share an android. mk file with multiple modules.
-- Build system can handle many details for you. For example, you are not allowed to list header files or other dependencies in the Android. mk file. These ndk build systems are automatically calculated and processed for you.
This also means that when you update to the new version of ndk, you should benefit from the support of the new toolchain/platform without modifying your android. mk file.
Note: These syntaxes are very similar to the Android. mk files distributed in the complete open-source Android source code. Although implemented by build system, their usage is different. The decision of this design is to make it easier for application developers to reuse the source code of the "external" library.
Simple Example:
-------------
Let's take a look at a simple example of "Hello JNI", which is under apps/Hello-JNI/project.
-- The 'src' directory is used to store Java source files.
-- The 'jni 'directory is used to store local source files, such as "JNI/hello-jni.c"
This source file implements a simple Shared Library: implements a local method and returns a string for the VM application.
-- The 'jni/Android. mk 'file describes how to generate a shared library. Its content is:
----------------- Android. mk ------------------------
Local_path: = $ (call my-DIR)
Include $ (clear_vars)
Local_module: = hello-JNI
Local_src_files: = hello-jni.c
Include $ (build_shared_library)
---------------------------------------------------
Now let's explain these lines separately
Local_path: = $ (call my-DIR)
The android. mk file must start with the local_path variable, which is used to locate the file in the tree. In this example, the macro function 'my-dir' is provided by the build system and is used to return the current directory path (including the Android. mk file itself)
Include $ (clear_vars)
The clear_vars variable is provided by the build system and specifies a gnu makefile file. This function clears all content starting with local _ (for example, local_module, local_src_files, local_static_libraries ), except local_path, this statement is required, because if all variables are global variables, all controllable compilation files must be parsed and executed in a separate GNU file.
Local_module: = hello-JNI
The local_module variable must be defined to distinguish every module in Android. mk. The file name must be unique and cannot contain spaces. Note: The compiler will automatically add some prefixes and suffixes to ensure the file is consistent. For example, it indicates that a dynamic Connection Library module is named "hello-JNI ", but it will eventually generate a "libhello-jni.so" file. However, the "hello-JNI" name is used to load the library in Java. Of course, if we use "Important Note:", the compilation system will not add a prefix for you, but to support the Android. mk file in the Android platform source code, it will also generate files such as libhello-jni.so.
Note: If you name your module 'libfoo', the compilation system will not add the prefix 'lib' and generate the libfoo. So file.
Local_src_files: = hello-jni.c
The local_src_files variable needs to include a list of C and C ++ source files, which will be compiled and aggregated into a module.
Note: you do not need to list header files and contained files here, because the compilation system will automatically calculate the relevant attributes for you, and the list in the source code will be passed directly to the compiler.
The default file extension of C ++ is ". cpp". We can define a different C file by defining a local_default_cpp_extension variable. Do not forget the "." point before initialization (that is, ". cpp" can work normally, but CPP cannot work normally)
Include $ (build_shared_library)
Build_shared_library is a script provided by the system and assigned to GNU makefile. It can collect all variables starting with local _ in your defined "include $ (clear_vars, it also determines which files should be compiled and which ones should be more accurate. The compiled file is "lib <module_name>. So". This is the shared library. We can also use the build_static_library compilation system to generate a file named "lib <module_name>. A" for dynamic library calls.
There are many complex examples under the samples directory, where the Android. mk file can be used for our reference.
Refer:
-----------------------
This is a list of variables. You can depend on or define them to Android. mk. You can define other variables you use, but the ndk discrimination system only keeps the following names:
-- Name starting with local _ (for example, local_module)
-- Name starting with private _, ndk _, or app _ (used internally)
-- Lowercase name (for example, 'My-dir', used internally)
If you need to define your own variables in Android. mk, we recommend using the my-prefix, a simple example:
----------------------------
My_sources: = Foo. c
Ifneq ($ (my_config_bar ),)
My_sources + = bar. c
Endif
Local_src_files + = $ (my_sources)
----------------------------
We continue:
Variables provided by ndk:
In your android. before the MK file is parsed, these GNU make variables are defined by the compilation system. Note that in some cases, ndk may be parsed several times, and each time it is parsed by the definition of different variables
Clear_vars
Clear_vars is a variable provided by the system. The function is to clear all content starting with local _. Before starting a new module, you must include this script.
Include ($ clear_vars)
Build_shared_library
Collect all information starting with local _ in the compilation script and decide to compile a target shared library from the listed source code. Note: You must define the local_module and local_src_files variables.
Include $ (build_shared_library)
Note: A file named lib <module_name>. So is generated.
Build_static_library
Used to build a static library. This static library will not be copied to your project/packages, but can be used for dynamic libraries.
(See the following introduction to local_static_library and local_whole_static_library)
For example:
Include $ (build_static_library)
Note that this will generate a module named lib <module_name>..
Prebuild_shared_library
In the compilation script, it is used to specify a pre-compiled dynamic library. Unlike build_shared_library and build_static_library, the pre-shared library of local_src_files must be a separate path (for example: Foo/libfoo. so) instead of source files.
You can reference the pre-compiled library in another module (see Docs/pribuilds.html)
Pribuild_static_library
This variable is similar to prebuild_shared_library, but it is for static libraries (for details, see Docs/prebuilds.html)
Target_arch
Target_arch indicates that the CPU name in the framework has been explicitly stated by the android open-source code. The arm here contains any arm-Independent Architecture and each independent CPU version.
Target_platform
Android platform name is parsed in Android. mk, such as "Android-3" corresponds to Android 1.5 system image, for the platform name corresponds to the list of Android system, please see Docs/STABLE-APIS.html
Target_arch_abi
The name of CPU + Abi is parsed in Android. mk.
Currently, two values are supported.
Armeabi for armv5te
Armeabi-v7a
Note that to Android ndk 1.6_r1, this value is simplified to "arm ". However, this value is redefined to better match what is used inside the Android platform
For more information, see Docs/CPU-ARCH-ABIS.html
Supported in future ndk versions. They will have a different name. Note that all ARM-based Abi will have a "target_arch" defined for arm, however, there may be different "target_arch_abi"
Target_abi
Link between the target platform and abi. here we need to define $ (target_platform)-$ (target_arch_abi) which are very useful, especially when you want to test whether a specific system image is in a real device Environment
By default, this is "android-3-armeabi"
(Android ndk 16_r1 uses "Android-3-arm" as the default version)
Macro functions provided by ndk
--------------------------------
The following is the macro function of GNU make. You must use "$ (call <function>)" to return a text message.
My-Dir
Returns the path of the last makefile, which is usually the path of the directory where Android. mk is located. It is defined before Android. mk starts.
Local--path is very useful.
Define the start position of the android. mk File
Local_path: = $ (call my-DIR)
... Declare a module
Include $ (local_path)/Foo/Android. mk
Local_path: = ($ call my-DIR)
... Declare another module
The problem here is that the second call "My-Dir" defines local_path to replace $ path with $ path/Foo, because it was previously executed.
For this reason, it is best to include everything else in Android. mk.
Local_path: = $ (call my-DIR)
... Declare a module
Local_path: = $ (call my-DIR)
... Declare another module
# Added at the end of Android. mk
Include $ (local_path)/Foo/Android. mk
If this is inconvenient, save the value of the first my-Dir call to another variable, for example
My_local_path: = $ (call my-DIR)
Local_path: = $ (my_local_path)
... Declare a module
Include $ (local_path)/Foo/Android. mk
Local_path: = $ (my_local_path)
... Declare another module
All-subdir-makefiles
Returns the location list of an android. mk file and the path of the current my-Dir file. For example
Sources/Foo/Android. mk
Sources/Foo/lib1/Android. mk
Sources/Foo/lib2/Android. mk
If sources/Foo/Android. mk contains this line of statements
Include $ (call all-subdir-makefiles)
Then, it will automatically include sources/Foo/lib1/Android. mk and sources/Foo/lib2/Android. mk.
This function can be used to provide the hierarchical structure of build system, a deep nested source code directory. Note that by default, ndk only searches
Sources/* Android. mk
This-makefile
Returns the path of the current makefile (that is, the function is called)
Parent-makefile
Returns the makefile inclusion tree, that is, the current file containing the makefile.
Grand-parent-makefile
Guess?
Import-Module
An android. mk function that allows you to find and contain another module by name, such
$ (Call import-module, <Name>)
This will find the Directory List of the module <Name> referenced by the ndk_module_path environment variable, and automatically include it
In Android. mk
For more information, see Docs/IMPORT-MODULE.html
Module variable description:
----------------------------------
The following variables are used to describe how to use your modules to compile the system. You can define some of them, for example
"Include $ (clear_vars)" and "include $ (build_xxx)", as previously written, $ (clear_vars) is a script that can cancel definition/clear all variables.
Local_path
This variable is used to give the path of the current file. Definition of the starting position of your android. mk instance:
Local_path: = $ (call my-DIR)
Note that this variable is not cleared by $ (clear_vars), and others are to be cleared (we can define several modules to a file)
Local_module
This is the name of your module. It must be unique among all your modules and cannot contain spaces. You must include any
$ (BUILD-XXX) is defined before the script.
By default, the module name determines the name of the generated file, such as lib <Foo>. So, which is the name of the foo module.
You can use local_module_filename to overwrite the default one.
Local_module_filename
This variable is optional and allows you to redefine the name of the generated file. By default, the module <Foo> will always generate the lib <Foo>. A or lib <Foo>. So file, which is a standard UNIX convention.
You can overwrite it with local_module_filename
Local_module: = foo-version-1
Local_module_filename: = libfoo
Note: You cannot write the file path or file extension to local_module_filename, which will be automatically processed by build system.
Local_src_files
This is the list of source files to be compiled in your module. Only list the files that will be passed to the compiler, because build system automatically calculates their dependencies for you.
Note: The source file names are relative to local_path. You can use the path component, for example
Local_src_files: = Foo. c \
Toto/bar. c
Note: Always use Unix-style slashes (/) when building the system. Windows-style slashes will not be processed.
Local_cpp_extension
This is an optional variable and can be defined as a source file with the file extension C ++. The default value is ". cpp", but you can change it, for example
Local_cpp_extension: =. cxx
Local_c_includes
An optional path list. Compared to the root directory of ndk, all source files (C, C ++, or assembly) are appended to the search path.
For example:
Local_c_includes: = sources/foo
Or
Local_c_includes: = $ (local_path)/../foo
These are placed before any corresponding flag.
Local_cflags/local_cppflags
When local debugging is started with ndk-GDB, local_c_includes is automatically used
Local_cflags
An optional compiler flag is passed when the C/C ++ source file is compiled.
This is useful for specifying additional macro definitions or compilation options.
Important: Do not change android. the optimization/debugging level in MK. MK sets the corresponding information for automatic processing for you, and will allow the ndk to generate useful data files used during debugging.
Note: In the Android-ndk-1.5_r1, only the C source file is used, not the C ++ source file. All Android build system matching behaviors have been corrected. (Now you can use local_cppflags for the c ++ source file to specify the flag)
It can use local_cflags + =-I <path> to specify additional include paths. However, it would be better if local_c_includes is used, because when local debugging is performed using ndk-gdk, the paths still need to be used.
Local_cxxflags
The alias of local_cppflags. Please note that this flag will disappear in future ndk versions
Local_cppflags
When only C ++ source code is compiled, an optional compiler flag is passed. They will appear after local_cflags.
Note: In the android NDK-1.5_r1 version, the corresponding flag can be applied to C or C ++ source files. This has been corrected when combined with the complete Android build system. (You can use local_cflags to specify C or C ++ source files)
Local_static_libraries
The list of static library modules (created through build_static_library) should be linked to this module. This is only to make the dynamic library sensitive.
Local_shared_library
The shared library list "module", which depends on the runtime. It is necessary to embed the corresponding information in the generated file during the link.
Local_whole_static_libraries
Local_whole_static_libraries is a variable used to indicate that the corresponding library module is used as the "entire file" to the linked program.
It is usually helpful when several static databases have circular dependencies. Note that when used to compile a dynamic library, this will force you to add the object files in all the static libraries to the final binary files. However, this is not certain when an executable program is generated.
Local_ldlibs
When the additional link flag list is used to compile your module, it is useful to pass the name by using a specific system library with the "-l" prefix. For example, which of the following old ones tells you to generate a module linked to/system/lib/libz. So during loading.
Local_ldlibs: =-LZ
Local_allow_undefined_symbols
By default, when attempting to compile a shared library, any undefined reference may cause an "undefined symbol" error. This helps capture bugs in your source code.
However, for some reason, if you need to disable this check, set the variable to "true. Note that the corresponding shared library may fail to be loaded during runtime.
Local_arm_mode
By default, the arm target binary is generated in "Thumb" mode, and each instruction has a 16-bit width. You can define this variable as "arm" if you want to force the generation of module object files in "arm" mode (32-bit command. For example:
Local_arm_mode: = arm
Note: You need to execute the compilation system to compile the specified source file by adding a suffix to the file name in arm mode. For example:
Local_src_files: = Foo. c bar. C. Arm
This tells the compilation system to always compile "bar. c" in arm mode and compile Foo. C using the value of local_arm_mode.
Note: Setting app_optim to "debug" in the application. mk file also forces the generation of arm binary files. This is because the bug in tool chain debugging does not process thumb code.
Local_arm_neon
Defining this variable as "true" will allow you to use arm advanced SIMD (also known as neon) in the internal functions of gcc in your c or C ++ source file ), and the neon command in the aggregate file.
You should define the armv7 command set for the "armeabi-v7a" Abi. Note that not all armv7 CPUs are extended based on the neon instruction set. You should execute the runtime to check the security of this Code.
In addition, you can specify a specific source file. For example, you can also compile a source file that supports the neon ". neon" suffix.
Local_src_files: = Foo. C. Neon bar. c zoo. C. Arm. Neon
In this example, "foo. C "will be compiled in thumb + neon mode," bar. C "compiled in thumb mode, zoo. C is compiled in ARM + neon mode.
Note: If you use two, the suffix ". neon" must appear after the suffix ". Arm ".
(That is, foo. C. Arm. Neon can work, but Foo. C. Neon. Arm does not work)
Local_disable_no_execute
Android ndk R4 began to support the "NX bit" security feature. It is enabled by default. If you need it, you can disable it by setting the variable to "true.
Note: This function does not modify abi and is only enabled on the kernel of armv6 and later CPU devices.
For more information, see:
Http://en.wikipedia.org/wiki/NX_bit
Http://www.gentoo.org/proj/en/hardened/gnu-stack.xml
Local_export_cflags
Define this variable to record the C/C ++ compiler flag set and add it to the local_cflags definition of any other modules in local_static_libraries and local_shared_libraries.
For example, define the "foo" module.
Include $ (clear_vars)
Local_module: = foo
Local_src_files: = Foo/Foo. c
Local_export_cflags: =-dfoo = 1
Include $ (build_static_library)
The other module is called bar and depends on the above module.
Include $ (clear_vars)
Local_module: = bar
Local_src_files: = bar. c
Local_cflags: =-dbar = 2
Local_static_libraries: = foo
Include $ (build_shared_library)
Then, when bar. C is compiled, the flag "-dfoo = 1-dbar = 2" will be passed to the compiler.
The output flag is added to the local_cflags of the module, so you can easily rewrite them. They also have transmission: If "Zoo" depends on "bar" and "bar" depends on "foo", "Zoo" also inherits all the flags output by "foo.
Finally, when compiling the module output flags, these flags are not used. In the preceding example, when Foo/Foo. C is compiled,
-Dfoo = 1 will not be passed to the compiler.
Local_export_cppflags
Similar to local_export_cflags, but applicable to the C ++ flag.
Local_export_c_includes
Similar to local_export_c_cflags, but only C can contain paths. This is useful if "bar. c" wants to include header files provided by the "foo" module.
Local_export_ldlibs
Similar to local_export_cflags, but only used for Link flag. Note that the introduced link flag will be appended to the local_ldlibs module, because the Unix connector works.
It is useful when module foo is a static library and the Code depends on the system library. Local_export_ldlibs can be used to output dependencies, for example:
Include $ (clear_vars)
Local_module: = foo
Local_src_files: = Foo/Foo. c
Local_export_ldlibs: =-llog
Include $ (build_static_library)
Include $ (clear_vars)
Local_module: = bar
Local_src_files: = bar. c
Local_static_libraries: = foo
Include $ (build_shared_library)
Here, at the end of the connector command, libbar. So will be compiled with the-llog parameter to indicate that it depends on the system logstore because it depends on foo.
Local_filter_asm
This variable defines a shell command that will be used to filter or aggregate files generated from your local_src_files.
When it is defined, the following situations will occur:
-- Any C or C ++ source file will be generated into a temporary aggregated file (instead of being compiled into the target file)
-- Any temporary aggregate file, any aggregate file listed in local_src_files will generate another temporary aggregate file through the local_filer_asm command
-- These filter aggregate files are compiled into target files.
In other words, if
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 --> $ objs_dir/bar. s -- 3 --> $ objs_dir/bar. o
The compiler corresponding to "1", the filter of "2", and the Assembly of "3. The filter must be an independent shell command as the name of the first parameter input file and the second name of the output file. For example, the file is:
Myasmfilter $ objs_dir/Foo. S. original $ objs_dir/Foo. s
Myasmfilter bar. S $ objs_dir/bar. s