Android mk file Introduction

Source: Internet
Author: User

Introduction:
Android. mk is used to describe your C and C ++ source code files to Android NDK. This document describes its syntax. Before reading the following content, let's assume that you have read the docs/OVERVIEW. TXT file and understood their roles and purposes.
I. Overview
An Android. mk file is used to describe your source code to the compilation system. Specifically:
(1) This file is a small part of GNU Makefile and will be parsed once or more times by the compilation system.
Therefore, you should minimize your declared variables and do not consider that some variables will not be defined during the parsing process.
(2) the syntax of this file allows you to organize your source code into modules. A module belongs to one of the following types:
1) static library 2) shared library, and only the shared library will be installed/copied to your application software package, although the static library can be used to generate a shared library.
You can define one or more modules in each Android. mk file. You can also use the same source code file in several modules.
(1) The compilation system handles many details for you. For example, you do not need to list header files and dependent files in your Android. mk file. The NDK compilation system automatically handles these problems for you. This also means that after you upgrade the NDK, you should get the new toolchain/platform support and do not need to change your Android. mk file.
Note: This syntax is very similar to the open source code of the publicly released Android platform. However, the method for implementing the compilation system is different. This is designed on purpose, it makes it easier for program developers to reuse the source code of external libraries.
Before describing the syntax details, let's look at a simple "hello world" example, for example, the following file:
Sources/helloworld. c
Sources/helloworld/Android. mk
'Helloworld. c' is a JNI shared library that provides native methods to return the "hello world" string. The corresponding Android. mk file will look like the following:
LOCAL_PATH: = $ (call my-dir)
Include $ (CLEAR_VARS)
LOCAL_MODULE: = helloworld
LOCAL_SRC_FILES: = helloworld. c
Include $ (BUILD_SHARED_LIBRARY)
Okay. Let's explain these lines of code:
LOCAL_PATH: = $ (call my-dir)
An Android. mk file must first define the LOCAL_PATH variable. It is used to search for source files in the Development tree. In this example, the macro function 'my-dir' is provided by the compilation system and used to return the current path (that is, the directory containing the Android. mk file ).
Include $ (CLEAR_VARS)
CLEAR_VARS is provided by the compilation system, specifying that gnu makefile clears many LOCAL_XXX variables for you (for example, LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, etc.), except LOCAL_PATH. This is necessary because all the compilation control files are in the same gnu make execution environment, and all the variables are global.
LOCAL_MODULE: = helloworld
The LOCAL_MODULE variable must be defined to identify each module you describe in the Android. mk file. The name must be unique and contain no spaces. Note that the compilation system automatically generates the appropriate prefix and suffix. In other words, a shared library module named 'foo' will generate the 'libfoo. so' file.
Important: If you name the library 'libhelloworld', the compilation system will not add any lib prefix or generate libhelloworld. so, this is to support Android from the source code of the Android platform. mk file, if you do need to do so.
LOCAL_SRC_FILES: = helloworld. c
The LOCAL_SRC_FILES variable must contain the C or C ++ source code file to be compiled and packaged into the module. Note that you do not need to list header files and contained files here, because the compilation system will automatically find the dependent files for you; just list the source code files directly transmitted to the compiler. [Note: The default C ++ source code file extension is '. cpp '. it is also possible to specify a different extension. As long as you define the LOCAL_DEFAULT_CPP_EXTENSION variable, do not forget the starting dot (that is, defined '. cxx', rather than 'cxx') (of course we will not change this step )]
Include $ (BUILD_SHARED_LIBRARY)
BUILD_SHARED_LIBRARY is a variable provided by the compilation system. It points to a GNU Makefile script (it should be shared_library.mk In the build/core directory) and is responsible for collecting data from the previous call of 'include $ (CLEAR_VARS) ', defines all information in the LOCAL_XXX variable and determines what to compile and how to do it correctly. And generate a static library based on its rules. Similarly, for static databases.
There are more complex examples in the sources/samples Directory. You can see the Android. mk file with annotations.
Ii. References
This is a list of variables that you should depend on or define in Android. mk. You can define other variables for your own use, but the NDK compilation system retains the following variable names:
-Name starting with LOCAL _ (for example, LOCAL_MODULE)
-Name starting with PRIVATE _, NDK _ or APP _ (used internally)
-Lowercase name (for internal use, for example, 'My-dir ')
If you want to define your own variables in Android. mk for convenience, we recommend that you use the MY _ prefix. A small example:
MY_SOURCES: = foo. c
Ifneq ($ (MY_CONFIG_BAR ),)
MY_SOURCES + = bar. c
Endif
LOCAL_SRC_FILES + = $ (MY_SOURCES)
1. GNU Make variable
These GNU Make variables are defined by the compilation system before parsing your Android. mk file. Note that in some cases, NDK may analyze Android. mk several times, and the definitions of some variables may vary.
(1) CLEAR_VARS: points to a compilation script. Almost all undefined LOCAL_XXX variables are listed in "Module-description. You must include this script before starting a new module. Include $ (CLEAR_VARS)
(2) BUILD_SHARED_LIBRARY: points to the compiling script, collects all the information you provide in the LOCAL_XXX variable, and decides how to compile the source code file you listed into a shared library. Note that you must define LOCAL_MODULE and LOCAL_SRC_FILES at least before including the file. Example:
Include $ (BUILD_SHARED_LIBRARY) (note that this will generate a file named lib $ (LOCAL_MODULE). so)
(3) BUILD_STATIC_LIBRARY: A BUILD_SHARED_LIBRARY variable is used to compile a static library. Static libraries will not be copied to your project/packages, but can be used to compile shared libraries (see the LOCAL_STATIC_LIBRARIES and LOCAL_STATIC_WHOLE_LIBRARIES described below)
Example: include $ (BUILD_STATIC_LIBRARY) (note that this will generate a file named lib $ (LOCAL_MODULE). ).
(4) TARGET_ARCH: name of the target CPU platform, as specified in the android open source code. If it is arm, it indicates that the command compatible with ARM is to be generated, which is irrelevant to the CPU architecture revision.
(5) TARGET_PLATFORM: name of the target Android platform when parsing Android. mk. For details, see/development/ndk/docs/stable-apis.txt.
Android-3-> Official Android 1.5 system images
Android-4-> Official Android 1.6 system images
Android-5-> Official Android 2.0 system images
(6) TARGET_ARCH_ABI: currently only two values are supported, armeabi and armeabi-v7a. In the current version, these two values are generally simply defined as arm, which can be better matched through redefinition within the android platform. Other ABI files will be described in later NDK versions. They will have different names. Note that all ARM-based ABI will define 'target _ ARCH 'As 'arm', but there will be different 'target _ ARCH_ABI'
(7) TARGET_ABI: A combination of the Target Platform and ABI, which is actually defined as $ (TARGET_PLATFORM)-$ (TARGET_ARCH_ABI) it is useful when you want to test a particular target system on a real device. By default, it will be 'android-3-arm '.
2. Module description Variables
The following variables are used to describe your module to the compilation system. You should define it between 'include $ (CLEAR_VARS) 'and 'include $ (BUILD_XXXXX. As described above, $ (CLEAR_VARS is a script that clears all these variables unless explicitly stated in the description.
(1) LOCAL_PATH: Specifies the path of the current file. You must define it at the beginning of Android. mk, which can be used as follows:
LOCAL_PATH: = $ (call my-dir)
This variable will not be cleared by $ (CLEAR_VARS), so each Android. mk only needs to be defined once (even if several modules are defined in a file ).
(2) LOCAL_MODULE: This is the name of your module. It must be unique and cannot contain spaces. You must define it before it contains any $ (BUILD_XXXX) script. The module name determines the name of the file to be generated. For example, if the name of a shared library module is <foo>, the file to be generated is lib <foo>. so. However, in your NDK generated file (or Android. mk or Application. mk), you should only involve (reference) other modules with normal names.
(3) LOCAL_SRC_FILES: list of source code files to be compiled. You only need to list the files to be passed to the compiler, because the compilation system automatically calculates dependencies for you. Note that the source code file names are relative to LOCAL_PATH. You can use the path section, for example:
LOCAL_SRC_FILES: = foo. c \
Toto/bar. c
Note: UNIX-style slashes (/) must be used in the generated files. The windows-style backslash will not be correctly processed.
(4) LOCAL_CPP_EXTENSION: This is an optional variable used to specify the extension of the C ++ code file. The default value is '. cpp', but you can change it, for example:
LOCAL_CPP_EXTENSION: =. cxx
(5) LOCAL_C_INCLUDES: Optional path configuration, starting from the root directory,
All sources (C, C ++ and Assembly). For example:
LOCAL_C_INCLUDES: = sources/foo
Or even:
LOCAL_C_INCLUDES: = $ (LOCAL_PATH)/../foo
It must be before any flag containing LOCAL_CFLAGS/LOCAL_CPPFLAGS.
(6) LOCAL_CFLAGS: Optional compiler options, used when compiling C code files. This may be useful, specifying an additional include path (relative to the top-level directory of the NDK), macro definition, or compilation options.
Important information: do not go to Android. in mk, you only need to change the optimization/debugging level in Application. if you specify the appropriate information in mk, the problem will be automatically handled for you. During debugging, The NDK will automatically generate useful data files.
(7) LOCAL_CXXFLAGS: Same as LOCAL_CFLAGS for C ++ source files
(8) LOCAL_CPPFLAGS: Same as LOCAL_CFLAGS, but applicable to both C and C ++ source files.
(9) LOCAL_STATIC_LIBRARIES: it should be linked to the static library list of this module (generated using BUILD_STATIC_LIBRARY), which is only meaningful to the shared library module.
(10) LOCAL_SHARED_LIBRARIES. Note: This will not append the listed modules to the compilation graph, that is, you still need to add them to the modules required by the program in Application. mk.
(11) LOCAL_LDLIBS: Additional Linker Options to be used to compile your module. This is useful for passing the name of the specified database using the "-l" prefix. For example, the following will tell the module generated by the linker to link to/system/lib/libz. so at the time of loading.
LOCAL_LDLIBS: =-lz
Look at the docs/STABLE-APIS.TXT to get a list of open system libraries that you can link to using the NDK release.
(13) LOCAL_ALLOW_UNDEFINED_SYMBOLS: by default, when attempting to compile a shared library, any undefined reference will cause an "undefined symbol" error. This will be of great help for capturing errors in your source code files. However, if you do not need to start this check for some reason, set this variable to 'true '. Note that the corresponding shared library may fail to be loaded at runtime. (Do not set this parameter to true)
(14) LOCAL_ARM_MODE: by default, the arm target binary is generated in the form of thumb (16 bits ), you can set this variable to arm if you want your module to be in the form of a 32-bit command.
'Arm '(32-bit instructions) mode. E. g .:
(15) LOCAL_ARM_MODE: = arm note that you can also tell the system to compile a specific type during compilation, such
(16) LOCAL_SRC_FILES: = foo. c bar. c. in this way, arm tells the system that bar is always used. c is compiled in arm mode. The following is the GNU Make 'function' macro, which must be evaluated by '$ (call <function>)'. They return the compile information.
(17) my-dir: return the directory path of the current Android. mk, relative to the top layer of the NDK compilation system. This is useful. It is defined at the beginning of the Android. mk file:
LOCAL_PATH: = $ (call my-dir)
(18) all-subdir-makefiles: returns a list of subdirectories in the current 'my-dir' path. For example, you can view the following directory levels:
Sources/foo/Android. mk
Sources/foo/lib1/Android. mk
Sources/foo/lib2/Android. mk
If sources/foo/Android. mk contains one line:
Include $ (call all-subdir-makefiles)
Then it automatically contains sources/foo/lib1/Android. mk and sources/foo/lib2/Android. mk. This function provides the compilation system with a deep nested code directory hierarchy. Note that by default, NDK will only search for files in sources/*/Android. mk.
(19) this-makefile: returns the path of the current Makefile (where this function is called)
(20) parent-makefile: return the path of the parent Makefile in the call tree. That is, the Makefile path that contains the current Makefile.
(21) grand-parent-makefile guess...
3. Use templates for Android. mk
Multiple executable programs, dynamic libraries, and static libraries can be generated in an Android. mk file.
(1) Compile the Application Template:
# Test Exe
LOCAL_PATH: = $ (call my-dir)
# Include $ (CLEAR_VARS)
LOCAL_SRC_FILES: = main. c
LOCAL_MODULE: = test_exe
# LOCAL_C_INCLUDES: =
# LOCAL_STATIC_LIBRARIES: =
# LOCAL_SHARED_LIBRARIES: =
Include $ (BUILD_EXECUTABLE)
(Cainiao-level explanation: = is the meaning of the value assignment, $ is to reference the value of a variable.) Add the source file path to local_src_files and add the header file path to local_c_pair des, local_static_libraries is added to the static library to be linked (*. a) Name: add the dynamic library to be linked in local_shared_libraries (*. so) name. local_module indicates the final name of the module, and build_executable indicates compiling in an executable program.
(2) Compile static library templates:
# Test static lib
Local_path: = $ (call my-DIR)
Include $ (clear_vars)
Local_src_files: = \
Helloworld. c
Local_module: = libtest_static
# Local_c_includes: =
# Local_static_libraries: =
# Local_shared_libraries: =
Include $ (build_static_library)
In general, it is similar to the above. build_static_library indicates compiling a static library.
(3) Compile the dynamic library template:
# Test shared lib
Local_path: = $ (call my-DIR)
Include $ (clear_vars)
Local_src_files: = \
Helloworld. c
LOCAL_MODULE: = libtest_shared
TARGET_PRELINK_MODULES: = false
# LOCAL_C_INCLUDES: =
# LOCAL_STATIC_LIBRARIES: =
# LOCAL_SHARED_LIBRARIES: =
Include $ (BUILD_SHARED_LIBRARY)
In general, it is similar to the above. BUILD_SHARED_LIBRARY indicates compiling a shared library.
The above three generation results are as follows, and the generic changes according to the specific target:
Out/target/product/generic/obj/EXECUTABLE
Out/target/product/generic/obj/STATIC_LIBRARY
Out/target/product/generic/obj/SHARED_LIBRARY
The target folders of each module are:
Executable program: XXX_intermediates
Static Library: XXX_static_intermediates
Dynamic library: XXX_shared_intermediates
In addition, in the Android. mk file, you can specify the final target installation path, which is specified using LOCAL_MODULE_PATH and LOCAL_UNSTRIPPED_PATH. Use the following macro to select different file system paths:
TARGET_ROOT_OUT: indicates the root file system.
TARGET_OUT: indicates the system file system.
TARGET_OUT_DATA: indicates the data file system.
Usage example:
LOCAL_MODULE_PATH: = $ (TARGET_ROOT_OUT)

Related Article

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.