Android. mk File Syntax details

Source: Internet
Author: User

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

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.