AS uses NDKBuild to create CPP project records
Since you need to use c++ and.so libraries, you must use NDK to document the process.
Now, we have some third party so and some header classes, and we need to use those classes and functions to do our thing, like the machine learning algorithm library, but how do we use those functions in the so? Mk and application. mk files, == note that this is only for nk-build projects ==, as AS2.2 now uses cmake to compile native projects by default.
The android. mk file is introduced on the website and will be covered later.
Where are the.so files and header files?
They should be stored in the app/ SRC /main/jni directory, including the required JNI interface files, as well as in the JNI directory for consistency.
Android.mk and application. mk files
- LOCAL_PATH: indicates the location of the file in the current project
my-dir
Is a function provided by the build system. - CLEAR_VARS: is also a variable provided by the build system that points to a special GNU Makefile that clears many LOCAL_XXX variables for you, such as LOCAL_MODULE, LOCAL_SRC_FILES, and LOCAL_STATIC_LIBRARIES, ==But the LOCAL_PATH variable is not cleared= =
- LOCAL_MODULE: Stores the name of the module you need to compile, for example
native-lib
“And finally the.so library is calledlibnative-lib.so
(The name is preceded by the lib field by default) - LOCAL_SRC_FILESSpecify where the file is, as in the current example
native-lib.cpp
. - Include $(BUILD_SHARED_LIBRARY) : Helps the system connect everything together
For other content, please refer to the official Google documentation. So let me just say a few things about this.
Issues that need attention
-
If the third-party libraries and jNI interface files are in the Jni directory (which is also the recommended directory mentioned at the beginning), you can write only one Android.mk file, which includes adding the third-party. So and. Otherwise you need to write two Android.mk files, one for loading the third party. so into the project, and one for compiling and generating your own JNI interface CPP library (i.e. Libnative-lib.so).
-
The differences between the two Android.mk files:
- Add. So library android. mk needs to be specified
include $(CLEAR_VARS) LOCAL_MODULE := nn LOCAL_SRC_FILES := $(LOCAL_PATH)/armeabi-v7a/lib/libnn.so LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/armeabi-v7a/include To specify a precompiled library, add the following identifier include $(PREBUILT_SHARED_LIBRARY) Copy the code
- Compile your own JNI interface CPP files
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := native-lib LOCAL_SRC_FILES := native-lib.cpp LOCAL_LDLIBS := -llog -landroid LOCAL_CFLAGS += -std=c++11 # This is the third party library compiled above, which is referenced here LOCAL_SHARED_LIBRARIES := nn include $(BUILD_SHARED_LIBRARY) Copy the code
- Add. So library android. mk needs to be specified
-
If two files are written in the same Android.mk file, the order should be to write their own JNI interface library mk, and then write the third party.
-
The application. mk file is relatively uniform, and generally everyone’s file is similar, so it can be used directly without any modification. The points that need to be paid attention to may be as follows:
APP_PLATFORM := android-15 APP_ABI := armeabi-v7a NDK_TOOLCHAIN_VERSION=4.9 APP_PIE := false APP_STL := gnuSTL_static APP_CFLAGS := -O3 -Wall -pipe \ -ffast-math \ -fstrict-aliasing -Werror=strict-aliasing \ -Wno-psabi -Wa,--noexecstack \ -DANDROID -DNDEBUG \ -std=c++11Copy the code
APP_PLATFORM
Version required and inAndroidManifest.xml
For example, if I specify 15 here, I need to be inxml
Also specifies at least 15 versions in:<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="26" /> Copy the code
- Try to use
APP_STL := gnustl_static
This version of c++ support is the best, there will be no library can’t find problems - If you need more support
c++11
, you need to specifyAPP_CFLAGS := -std=c++11
, the sentence is inAndroid.mk
You’d better add it to the listc++11
Library functions could not be found.
Gradle file adjustments
Gradle is also configured according to cmake. If you want to use ndK-build, you need to modify Gradle.
-
Instead of cmake, replace ndkBuild with ndkBuild, which is a configuration function.
externalNativeBuild { ndkBuild { // Sets optional flags for the C compiler. cFlags "-D_EXAMPLE_C_FLAG1"."-D_EXAMPLE_C_FLAG2" // Sets a flag to enable format macro constants for the C++ compiler. cppFlags "-D__STDC_FORMAT_MACROS"}}Copy the code
-
Add the following under Android {} to specify the makefile path, which is required:
externalNativeBuild { ndkBuild { path "src/main/jni/Android.mk"}}Copy the code
-
Build armeabi-v7A = armeabi-v7a = armeabi-v7a = armeabi-v7A = armeabi-v7A = armeabi-v7A
buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' ndk { abiFilter "armeabi-v7a" } } debug { minifyEnabled false ndk { abiFilter "armeabi-v7a"}}}Copy the code
-
If More than one file was found with OS independent path, you need to remove the following specified, please refer to my article AS the NDK-build CPP problem
// Comment out the following code sourceSets.main { // jniLibs.srcDir('src/main/libs') } Copy the code