Android.mk file writing

Source: https://www.jianshu.com/p/9aab51f4cd6f

1. Introduction to Android.mk

Android.mk is a makefile provided by Android, and it is used to compile and generate exe (binary executable file), so (dynamic library file), a (static library file), jar (jar package) and apk files. Android.mk and one or more .c source files are placed in the same directory as a module, and the module is compiled through the mm or mmm command to generate the required files, such as: binary executable files, dynamic libraries , static library, jar package and apk. You can refer to the original Android.mk file to modify it to write your own Android.mk file, so you need to master the basic syntax of Android.mk.

The entire android source code can be compiled through the make command; the mm command compiles the current directory (compilation of a separate module); the mmm command is used to compile the specified directory (compilation of a separate module).

2. Basic syntax of Android.mk

2.1 Android.mk basic grammar format example:

  • Configure environment variables: define the relative path of the current module
    LOCAL_PATH := $(call my-dir)
  • Clear the current environment variables: all environment variables except LOCAL_PATH
    include $(CLEAR_VARS)
  • Compile the file name of the generated object file
    LOCAL_MODULE := test
  • Source files required to compile this module: use the connector "\" to connect multiple source files
    LOCAL_SRC_FILES := test.c
  • The format (type) of the target file generated by compilation:
    include $(BUILD_EXECUTABLE)

2.2 The target file type generated by compilation:

  • EXECUTABLES: binary executables
  • SHARED_LIBRARIES: dynamic library files
  • STATIC_LIBRARY: static library file
  • JAVA_LIBRARIES:jar包
  • PACKAGE:apk

2.3 Reference resources in Android.mk:

  • Reference system static library —> LOCAL_STATIC_LIBRARIES += libxxx
  • Reference system dynamic library —> LOCAL_SHARED_LIBRARIES += libxxx

For example, refer to the system dynamic library: LOCAL_SHARED_LIBRARIES += liblog

  • Reference third-party library files —> LOCAL_LDFLAGS := -L/PATH -lxxx

For example, refer to a third-party dynamic library: LOCAL_LDFLAGS := -L$(LOCAL_PATH)/lib/ -ltest3

For example, refer to a third-party static library: LOCAL_LDFLAGS := $(LOCAL_PATH)/lib/libtest2.a

  • Reference third-party header files —> LOCAL_C_INCLUDES := path

如:LOCAL_C_INCLUDES = $(INCLUDES)

  • Introduce header files, etc. —> LOCAL_xxx := xxx
  • Introduce jar packages, etc. —> LOCAL_xxx := xxx

Such as importing shared (dynamic) jar packages: LOCAL_STATIC_JAVA_LIBRARIES := libarity android-support-v4 guava

3 Android.mk manages source code files (specify source code files required for compilation)

3.1 Compile multiple source code files

Question: There are multiple source code files under one project, how to manage and compile them in a unified way?

 

 

Project directory structure.png

 

Answer: Add multiple source files under the project to the variable LOCAL_SRC_FILES of Android.mk
(1) Method 1: Use the connector "\" to add each source file to Android.mk (2) Method 1: Use the system The provided function handles

 

The method of compiling multiple source code files.png

 

Compile and generate target file.png

 

3.2 One Android.mk file is compiled to generate multiple target files

Question: How to compile and generate multiple target files in one Android.mk file? Such as generating multiple bin files (binary executable files), .so files (dynamic library files) and .a files (static library files) at the same time.
Answer: The LOCAL_PATH variable remains unchanged, other variables are copied and reconfigured

A method of compiling and generating multiple target files from one Android.mk file.png

 

An Android.mk file is compiled to generate multiple target files.png

4 Android.mk manages the target file types generated by compilation

4.1 Compile and generate exe, so or a file —> source file is C/C++ file

  • How to compile and generate a binary executable file exe-> modify the compilation type to:BULID_EXECUTABLE
  • How to compile and generate a dynamic library file so-> modify the compilation type to:BULID_SHARED_LIBRARY
  • How to compile and generate a static library file a-> modify the compilation type to:BULID_STATIC_LIBRARY

(1) Specify the file type generated by compilation

Specify the file type generated by compilation.png

(2) Compile and generate various target files

Compile and generate various target files.png

4.2 Compile and generate jar package or apk file —> source file is java file

(1) Compile and generate jar package

  LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
  LOCAL_SRC_FILES := $(call all-subdir-java-files)
  LOCAL_MODULE := com.test.myjar
  include $(BUILD_JAVA_LIBRARY)
  • Static jar package: include $(BUILD_STATIC_JAVA_LIBRARY)
    is a JAR file packaged with .class files, which can be run on any java virtual machine
  • Dynamic jar package: include $(BUILD_JAVA_LIBRARY) is
    a jar file packaged with .dex based on the static jar package. .dex is the file format used by the android system.

(2) Compile and generate apk
syntax:

  LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
  LOCAL_SRC_FILES := $(call all-subdir-java-files)
  LOCAL_PACKAGE_NAME := LocalPackage
  include $(BUILD_PACKAGE)
  • LOCAL_SRC_FILES := $(call all-subdir-java-files) —> Get all java files in the current directory as source files
  • LOCAL_PACKAGE_NAME := LocalPackage —> The compiled target file name is LocalPackage
  • include $(BUILD_PACKAGE) —> The target file type generated by compilation is apk

: If the apk depends on the jar package, the syntax for importing the jar package and library files in the apk is

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_JAVA_LIBRARIES := share-library
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := LocalPackage
include $(BUILD_PACKAGE)

  • Import static jar package in apk —> LOCAL_STATIC_JAVA_LIBRARIES := static-library
  • Import dynamic (system/shared) jar package in apk —> LOCAL_JAVA_LIBRARIES := share-library
    such as:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_STATIC_JAVA_LIBRARIES := libarity android-support-v4 guava

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_SDK_VERSION := current

LOCAL_PACKAGE_NAME := Calculator

include $(BUILD_PACKAGE)

5. Android.mk introduces various libraries and header files

5.1 Introduce the system library into the project

工程如何引入系统库: Add system libraries used in source files to Android.mk, ie LOCAL_SHARED_LIBRARIES += libxxx. libxxx represents the system library name.
(1) For example: the system function ALOGE("") is used in the new source file main.cpp

#include <stdio.h>
#define LOG_TAG "Main"
#include <utils/Log.h>
int main(void)
{
   ALOGE("test");
   return 0;
}

(2) Add the source file main.cpp to Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= test3
LOCAL_C_ALL_FILES := src/main.cpp
LOCAL_SRC_FILES := $(LOCAL_C_ALL_FILES)
LOCAL_MODULE_PATH := $(LOCAL_PATH)/bin
include $(BUILD_EXECUTABLE)

(3) Direct compilation error: it is useless to introduce the system library files used in the source code into the project

compile error.png

 

(4) Modify Android.mk: Add the library liblog corresponding to the system function used in the source file main.cpp, that is, add LOCAL_SHARED_LIBRARIES += liblog

Import system library file.png


(5) Recompile successfully

Compile successfully.png

5.2 Introducing third-party libraries into the project

Description 1: Create a new source file test1.cpp

#include <stdio.h>
void call_test(void)
{
   printf("test1\n");
   return;
}

Note 2: The Android.mk file is as follows

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE:= libtest3
LOCAL_C_ALL_FILES := src/test1.cpp
LOCAL_SRC_FILES := $(LOCAL_C_ALL_FILES)
LOCAL_MODULE_PATH := $(LOCAL_PATH)/lib
include $(BUILD_SHARED_LIBRARY)


include $(CLEAR_VARS)
LOCAL_MODULE:= test3
LOCAL_C_ALL_FILES := src/main.cpp
LOCAL_SHARED_LIBRARIES += liblog
LOCAL_SRC_FILES := $(LOCAL_C_ALL_FILES)
LOCAL_MODULE_PATH := $(LOCAL_PATH)/bin
include $(BUILD_EXECUTABLE)

Remarks: Compiling test1.cpp generates a dynamic library libtest3.so file (equivalent to a third-party library file), and compiling main.cpp generates a binary executable test3 file.

5.2.1 Introducing a third-party dynamic library

工程如何引入第三方动态库: Add the third-party library used in the source file to Android.mk, ie LOCAL_LDFLAGS := -L/Path -lxxx. Path represents the path of the third-party library, xxx represents the name of the third-party library or the name of the target file compiled and generated (1) For example: the project source file main.cpp calls the function
in test1.cpp through extern

Call functions in other files.png


(2) Direct compilation will report an error:

compile error.png


(3) Android.mk needs to be modified: import the third-party library libtest3.so file, that is, add: LOCAL_LDFLAGS := -L ./lib/ -ltest3 or LOCAL_LDFLAGS := -L$(LOCAL_PATH)/lib/ -ltest3

Import third-party library files.png


(4) Recompile successfully

Compile successfully.png

5.2.2 Introducing third-party header files

Note 1: The header file test1.h file is as follows

#ifndef TEST1 H
#define TEST1 H
extern void call_test(void);
#endif

Note 2: The Android.mk file is as follows

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE:= libtest3
LOCAL_C_ALL_FILES := src/test1.cpp
LOCAL_SRC_FILES := $(LOCAL_C_ALL_FILES)
LOCAL_MODULE_PATH := $(LOCAL_PATH)/lib
include $(BUILD_SHARED_LIBRARY)


include $(CLEAR_VARS)
LOCAL_MODULE:= test3
LOCAL_LDFLAGS := -L ./lib/ -ltest3
#LOCAL_LDFLAGS := -L$(LOCAL_PATH)/lib/ -ltest3
LOCAL_C_ALL_FILES := src/main.cpp
LOCAL_SHARED_LIBRARIES += liblog
LOCAL_SRC_FILES := $(LOCAL_C_ALL_FILES)
LOCAL_MODULE_PATH := $(LOCAL_PATH)/bin
include $(BUILD_EXECUTABLE)

工程如何引入第三方头文件: Configure the header file path in the Android.mk file LOCAL_C_INCLUDES := Path. Path represents the path of the header file.
(1) For example: the project source file main.cpp calls the function in test1.cpp, through the header file

main.cpp.png
(2) When the path of the header file is quite different from the path of main.cpp, the header file can be imported in the following way

main.cpp.png

Configuration header file path.png

5.2.3 Introducing a third-party static library

工程如何引入第三方静态库: Add the third-party library static library used in the source file to Android.mk, ie LOCAL_LDFLAGS := Path. Path represents the path of the static library of the third-party library.

Introduce third-party static library.png 

6. Use judgment statement in Android.mk

grammar:

ifeq($(VALUE), x)  
  do_yes
else
  do_no
endif

or

ifneq($(VALUE), x)  
  do_yes
else
  do_no
endif

like:

The difference between a static library and a dynamic library
First of all, let's look at what a library is. A library (Library) is simply a piece of compiled binary code, plus a header file that can be used by others.
When will we use the library? One situation is that some code needs to be used by others, but we don't want others to see the source code, so we need to encapsulate it in the form of a library, and only expose the header file . Another situation is that for some code that will not undergo major changes, if we want to reduce the compilation time, we can package it into a library, because the library is a compiled binary, and we only need to link it when compiling. , without wasting compilation time.
It is mentioned above that the library needs Link when it is used. There are two ways of Link, static and dynamic, so static library and dynamic library are produced.
Static library
A static library is a statically linked library (.lib under Windows, .a under Linux and Mac). The reason why it is called static is because the static library will be copied directly when compiling and copied to the target program, and this code will not change in the target program.
The benefits of static libraries are obvious. After the compilation is completed, the library files are actually useless. The target program has no external dependencies and can be run directly. Of course, its disadvantage is also obvious, that is, the size of the target program will be increased.
Dynamic library
A dynamic library is a dynamic link library (.dll under Windows, .so under Linux, .dylib under Mac). Contrary to the static library, the dynamic library will not be copied into the target program during compilation, and only the reference to the dynamic library will be stored in the target program. The dynamic library will not be actually loaded until the program is running.
The advantage of a dynamic library is that it does not need to be copied into the target program, does not affect the size of the target program, and the same library can be used by multiple programs (for this reason, a dynamic library is also called a shared library). At the same time, the feature of loading only at compile time also allows us to replace the library at any time without recompiling the code. The main problem with dynamic libraries is that dynamic loading will cause some performance loss, and the use of dynamic libraries will also make the program depend on the external environment. If the environment lacks a dynamic library or the version of the library is incorrect, the program will fail to run (lib not found error that is popular under Linux).

Guess you like

Origin blog.csdn.net/weixin_37830912/article/details/128850803