Please indicate the original blog address for reprinting
Write at the front
When Ubuntu compiles system source code, it is necessary to configure all kinds of things in the mk file. Compared with typing code in Android Studio, it is really TMD trouble (at that time, there seemed to be tens of millions of horses running around), but the mentality gradually improved after that. Everyone is the same. At first, they don't understand the new and temporarily see the advantages, heart. Always resist, always the first time resist it, deny him. In fact, this often affects our growth. For all kinds of new things, we should face them instead of escaping them. Only in this way can we really grow up.
Ha-ha, stop pulling eggs, let's get to the point.
Introduction to Android mk
What is mk file
The Android.mk file is used to inform the NDK Build system about Source. It is part of the GNU Makefile and will be parsed once or more by Build System.
Simple example
First, let's look at the simplest example, compiling an ordinary apk.
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Whether to open confusion LOCAL_PROGUARD_ENABLED := disabled LOCAL_MODULE_TAGS := optional # Using platform signature LOCAL_CERTIFICATE := platform # Specify the src directory LOCAL_SRC_FILES := $(call all-java-files-under, src) # Specify the res directory LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/res # Specify apk compilation LOCAL_PACKAGE_NAME := AppDemo include $(BUILD_PACKAGE)
interpretative statement
- LOCAL_PATH := $(call my-dir)
Each Android.mk file must begin with the definition of LOCAL_PATH. It is used to find source files in development tree.
- include $(CLEAR_VARS)
The CLEAR_VARS variable is provided by Build System. And point to a specified GNU Makefile, which is responsible for cleaning up many LOCAL_xxx.
For example: LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES and so on. But LOCAL_PATH is not cleaned up.
- LOCAL_MODULE_TAGS :
Represents when a version will be compiled
LOCAL_MODULE_TAGS : =user eng tests optional user: Refers to the module that only exists in the uuuuuuuuuuu user Compile only under version eng: Refers to the module that only exists in the uuuuuuuuuuu eng Compile only under version tests: Refers to the module that only exists in the uuuuuuuuuuu tests Compile only under version optional:Refers to the module compiled under all versions
- include $(BUILD_PACKAGE) represents the generation of an apk, which can be of many types
BUILD_SHARED_LIBRARY #Generate a dynamic library BUILD_STATIC_LIBRARY #Generate a static library BUILD_PACKAGE #Generate an APK
Specify the directory where the generated apk is stored
Default condition
When no APK is specified to generate directories, the default directory is system/app/{LOCAL_PACKAGE_NAME}/{LOCAL_PACKAGE_NAME}.apk.
For example, our example LOCAL_PACKAGE_NAME above is AppDemo, so the generated apk directory is
system/app/AppDemo/AppDemo.apk
Specified directory
If we want to specify the generated apk directory, we can configure it through LOCAL_MODULE_PATH. For example, we want to specify the generated aok directory as system/vendor/operator/app, which we can configure.
LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/operator/app
The $(TARGET_OUT) represents / system, so that we can see the generated apk in, system/vendor/operator/app.
What if we want our generated apk to be placed in the system/priv-app directory?
The first method is to specify LOCAL_MODULE_PATH. In the above explanation, we already know that $(TARGET_OUT) stands for / system. Then the generated apk wants to be placed in system/priv-app. We can configure it this way.
LOCAL_MODULE_PATH := $(TARGET_OUT)/priv-app
In the second way, we can configure it directly so that the generated apk can also be placed in system/priv-app.
LOCAL_PRIVILEGED_MODULE := true
What if we want our generated apk to be placed in the data/app directory?
We can specify this directly so that the generated apk will be placed in the data/app directory
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)/
Reference to third-party jar packages
Reference to a jar package
For example, libs in our current directory has a CommonUtil. jar package, and we want to refer to it in two steps
Step 1: Declare the directory where our jar package is located
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES: = CommonUtil:/libs/CommonUtil.jar This line of code probably means to declare a variable CommonUtil whose value is/libs/CommonUtil.jar.
include $(CLEAR_VARS) LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := CommonUtil:/libs/CommonUtil.jar include $(BUILD_MULTI_PREBUILT)
Step 2. Refer to the variables we declare for the jar package
Refer to CommonUtil as we stated above
LOCAL_STATIC_JAVA_LIBRARIES := CommonUtil
Referencing multiple jar packages
Referencing multiple jar packages is actually the same way as referring to a jar package, except that we need to pay attention to the syntax.
Step 1: First declare the location of multiple jar packages
include $(CLEAR_VARS) LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := MeituCloudHelper:/libs/CommonUtil.jar \ BaiduLBS:/libs/BaiduLBS_Android.jar \ logger:/libs/logger.jar include $(BUILD_MULTI_PREBUILT)
Step 2: Refer to the variables of multiple jar packages we declare
LOCAL_STATIC_JAVA_LIBRARIES := CommonUtil \ BaiduLBS \ logger
For your understanding, here are some mk files posted first.
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Whether to open confusion LOCAL_PROGUARD_ENABLED := disabled LOCAL_MODULE_TAGS := optional # Using platform signature LOCAL_CERTIFICATE := platform # Specify the src directory LOCAL_SRC_FILES := $(call all-java-files-under, src) # Specify the res directory LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/res # Locally compiled directories LOCAL_PACKAGE_NAME := AppDemo LOCAL_STATIC_JAVA_LIBRARIES := CommonUtil \ BaiduLBS \ logger include $(BUILD_PACKAGE) include $(CLEAR_VARS) LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := CommonUtil:/libs/CommonUtil.jar \ BaiduLBS:/libs/BaiduLBS_Android.jar \ logger:/libs/logger.jar include $(BUILD_MULTI_PREBUILT)
Reference to so Library
Suppose we have armeabi-v7a and arm64-v8a directories in the lib directory under our current directory, which are libBaiduMapSDK_base_v4_2_1.so and libBaiduMapSDK_base_v4_2_1.so, respectively. If we want to package these so libraries when compiling the apk, how do we configure them in the mk file?
Generally speaking, there are two ways of writing
The first way of writing
The first step is to configure the following contents directly in the mk file, configure the location of our so library files, which can be at the beginning or end of the file.
#==================================================== include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_MODULE_SUFFIX := .so LOCAL_MODULE := libBaiduMapSDK_base_v4_2_1 LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_SRC_FILES_arm :=libs/armeabi-v7a/libBaiduMapSDK_base_v4_2_1.so LOCAL_SRC_FILES_arm64 :=libs/arm64-v8a/libBaiduMapSDK_base_v4_2_1.so LOCAL_MODULE_TARGET_ARCHS:= arm arm64 LOCAL_MULTILIB := both include $(BUILD_PREBUILT) #==================================================== #==================================================== include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_MODULE_SUFFIX := .so LOCAL_MODULE := libBaiduMapSDK_map_v4_2_1 LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_SRC_FILES_arm :=libs/armeabi-v7a/libBaiduMapSDK_map_v4_2_1.so LOCAL_SRC_FILES_arm64 :=libs/arm64-v8a/libBaiduMapSDK_map_v4_2_1.so LOCAL_MODULE_TARGET_ARCHS:= arm arm64 LOCAL_MULTILIB := both include $(BUILD_PREBUILT)
Step 2: Refer to our so Library
Add the following between include $(CLEAR_VARS) and include $(BUILD_PACKAGE)
LOCAL_REQUIRED_MODULES := libBaiduMapSDK_base_v4_2_1 \ libBaiduMapSDK_map_v4_2_1 \ LOCAL_JNI_SHARED_LIBRARIES := libBaiduMapSDK_base_v4_2_1\ libBaiduMapSDK_map_v4_2_1\
After configuring, the mk file will probably look like this
include $(CLEAR_VARS) ---- # Elimination of a number of elements LOCAL_REQUIRED_MODULES := libBaiduMapSDK_base_v4_2_1 \ libBaiduMapSDK_map_v4_2_1 \ LOCAL_JNI_SHARED_LIBRARIES := libBaiduMapSDK_base_v4_2_1\ libBaiduMapSDK_map_v4_2_1\ include $(BUILD_PACKAGE)
The second way of writing
The second is actually similar to the first, except that the declaration of the so library is extracted.
Step 1: For example, we extract the following code into the lib/baidumap.mk mk file
#==================================================== include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_MODULE_SUFFIX := .so LOCAL_MODULE := libBaiduMapSDK_base_v4_2_1 LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_SRC_FILES_arm :=libs/armeabi-v7a/libBaiduMapSDK_base_v4_2_1.so LOCAL_SRC_FILES_arm64 :=libs/arm64-v8a/libBaiduMapSDK_base_v4_2_1.so LOCAL_MODULE_TARGET_ARCHS:= arm arm64 LOCAL_MULTILIB := both include $(BUILD_PREBUILT) #==================================================== #==================================================== include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_MODULE_SUFFIX := .so LOCAL_MODULE := libBaiduMapSDK_map_v4_2_1 LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_SRC_FILES_arm :=libs/armeabi-v7a/libBaiduMapSDK_map_v4_2_1.so LOCAL_SRC_FILES_arm64 :=libs/arm64-v8a/libBaiduMapSDK_map_v4_2_1.so LOCAL_MODULE_TARGET_ARCHS:= arm arm64 LOCAL_MULTILIB := both include $(BUILD_PREBUILT)
The second step is to add the following statement to the original Android.mk file to indicate that the / lib/baidumap.mk file will be include d.
include $(LOCAL_PATH)/lib/baidumap.mk
Step 3: Refer to our so Library
include $(CLEAR_VARS) ---- # Elimination of a number of elements LOCAL_REQUIRED_MODULES := libBaiduMapSDK_base_v4_2_1 \ libBaiduMapSDK_map_v4_2_1 \ LOCAL_JNI_SHARED_LIBRARIES := libBaiduMapSDK_base_v4_2_1\ libBaiduMapSDK_map_v4_2_1\ include $(BUILD_PACKAGE)
In fact, the first method is not much different from the second method. The second method is only to configure the so library file independently into the mk file, compared with the first method. However, I would recommend the second method. After all, it is more in line with the object-oriented thinking, and it will be more convenient to reuse later.
Reference to aar package
Step 1: First declare the location of the aar package
include $(CLEAR_VARS) LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += inveno_meitu_ui_sdk:libs/meitu_sdk-release_201709291605.aar LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += inveno_detail_info_sdk:libs/detail_info_sdk-release.aar include $(BUILD_MULTI_PREBUILT)
Step 2: Refer to our declared aar variable
LOCAL_STATIC_JAVA_AAR_LIBRARIES += inveno_meitu_ui_sdk LOCAL_STATIC_JAVA_AAR_LIBRARIES += inveno_detail_info_sdk
Step 3: Add the resources in the referenced aar package
LOCAL_AAPT_FLAGS += \ --auto-add-overlay \ --extra-packages com.inveno.basics \ --extra-packages com.inveno.detailinfosdk \
Android mk file configuration signature
We know that there are four sets of default signatures in the build/target/product/security directory, and Android.mk is used in the compiled APK:
- 1. Teskey: General APK, used by default.
- 2. platform: The APK completes some core functions of the system. After the access test of the folders existing in the system,
The UID of the process in which the APK is compiled in this way is system. - 3. shared: The APK needs to share data with the home/contacts process.
- 4. Media: This APK is a part of media/download system.
Give an example.
All APK s in the system use android.uid.system as the shared UID. They will first add android:sharedUserId="android.uid.system" to the manifest node. Then add LOCAL_CERTIFICATE: = platform to Android.mk. See Settings, etc. All APK s in the system use android.uid.shared as the shared UID. android:sharedUserId="android.uid.shared" will be added to the manifest node. Then add LOCAL_CERTIFICATE: = shared in Android.mk. See Launcher et al. All APK s in the system use android.media as a shared UID. android:sharedUserId="android.media" will be added to the manifest node. Then add LOCAL_CERTIFICATE: = media to Android.mk. See Gallery et al.