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 projectmy-dirIs 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 examplenative-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 examplenative-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

  1. 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).

  2. 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
  3. 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.

  4. 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_PLATFORMVersion required and inAndroidManifest.xmlFor example, if I specify 15 here, I need to be inxmlAlso specifies at least 15 versions in:
      <uses-sdk
      android:minSdkVersion="15"
      android:targetSdkVersion="26" />
      Copy the code
    • Try to useAPP_STL := gnustl_staticThis version of c++ support is the best, there will be no library can’t find problems
    • If you need more supportc++11, you need to specifyAPP_CFLAGS := -std=c++11, the sentence is inAndroid.mkYou’d better add it to the listc++11Library 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.

  1. 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
  2. Add the following under Android {} to specify the makefile path, which is required:

        externalNativeBuild {
            ndkBuild {
                path "src/main/jni/Android.mk"}}Copy the code
  3. 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
  4. 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