Two ways to compile android studio ndk (ndk-build and cmake) configuration

Android uses armeabi-v7a by default

1.ndk-build

Load JNI 1.java layer code dynamically
:

    static {
    
    
        System.loadLibrary("MyLibrary"); // libxxx.so库的  libMyLibrary.so
    }

2. jni C++
(1) Create a new jni directory in the main directory, the .cpp in it will eventually generate a .so library and load it into the apk

在这里插入代码片

(2) Create Android.mk Application.mk file compilation script

Android.mk

    #每个Android.mk文件必须以LOCAL_PATH开头,在整个开发中,它通常别用做定位资源文件,例如,功能宏my-dir提供给编译系统当前的路径。
    LOCAL_PATH := $(call my-dir)
    
    #CLEAR_VARS指编译系统提供一个特殊的GUN MakeFile来为你清除所有的LOCAL_XXX变量,LOCAL_PATH不会被清除。使用这个变量是因为在编译系统时,所有的控制文件都会在一个GUN Make上下文进行执行,而在此上下文中所有的LOCAL_XXX都是全局的。
    include $(CLEAR_VARS)
    
    #LOCAL_MODULE变量是为了确定模块名,并且必须要定义。这个名字必须是唯一的同时不能含有空格。会自动的为文件添加适当的前缀或后缀,模块名为“foo”它将会生成一个名为“libfoo.so”文件。
    LOCAL_MODULE := myjni
    
    #包含一系列被编译进模块的C 或C++资源文件
    LOCAL_SRC_FILES := JNI_C++.cpp
    
    #指明一个GUN Makefile脚本,并且收集从最近“include$(CLEAR_VARS)”下的所有LOCALL_XXX变量的信息,最后告诉编译系统如何正确的进行编译。将会生成一个静态库hello-jni.a文件或者动态库libhello-jni.so。
    include $(BUILD_SHARED_LIBRARY)

Summary:
LOCAL_PATH is the directory where the command is called. In which directory you use the cmd command, its path address will be returned here.
LOCAL_MODULE What is the name of the file you generated. After the output, it will automatically add lib and before and after the name. so
LOCAL_SRC_FILES which file to compile

Application.mk
is not available. It mainly specifies the so called library name and the compiled so corresponding to the CPU platform.
If not, you can set it in build.gradle. At this time, use the system to compile instead of using ndk-build

    APP_MODULES := MyJni
    APP_ABI := all all代表全平台

3. Compilation method selection :
set the library file name (the generated so file name) in build.gradle under the app module directory. Find the defaultConfig item of the gradle file and add the following content:

//第一种是将c++ 文件生成.so 库
defaultConfig {
    
     
    ...... 
    //1.指定生成模块名,架构
    ndk{
    
     
        moduleName "JniLibName"  //生成的so名字
        ldLibs "log", "z", "m"  //添加依赖库文件,如果有log打印等 
        abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定cpu体系结构下的so库。 
    } 
}
//2.指定编译Android.mk目录
externalNativeBuild {
    
      
          ndkBuild {
    
     path file("src/main/java/jni/Android.mk") 
    } 
}
//3.指定jni代码目录
sourceSets {
    
          
    main {
    
    
        jni.srcDirs('src/main/java/jni')
    }
}
此种生成的so文件在app/build/intermediates/ndkBuild/debug下



//第二种是 指定将已经有的.so 编译进apk里面
    sourceSets {
    
    
        main {
    
    
            jniLibs.srcDirs('.\\libs')        
            这种是指定.so 文件编译进apk里面,如果在main目录下已经有个JniLibs目录则不用指定,编译时自动会编译进去
        }
    }

2. Cmake method (commonly used)

Main/java same level directory jni jniLibs After these two directories are manually created, there is no need to specify the jni code directory and so library path in build.gradle.
Insert picture description here

Cmake method creation steps:
1. Set the cmake compilation mode in buidl.gradle, set the compilation architecture, source so library path
2. Create CMakeLists.txt in the same level directory (need to be specified in buidl.gradle)
3. Create in the jni directory Create CMakeLists.txt, generate so library

(1)build.gradle

android {
    
    
    defaultConfig {
    
    
....
        externalNativeBuild {
    
    
            cmake {
    
    
                cppFlags ""
            }
        }
        ndk {
    
     //设置打包时只编译so库armeabi-v7a
           moduleName "MyLibrary"
           abiFilters  'armeabi-v7a', 'arm64-v8a' ,'x86', 'x86_64'  
        }
    }
  externalNativeBuild {
    
     //设置cmake编译脚本
        cmake {
    
    
            path "CMakeLists.txt"
        }
    }
    sourceSets {
    
     //注意如果自己在src/java创建了 jni jniLibs则不用指定,根据需要自己设定
        main {
    
    
            manifest.srcFile 'src/main/AndroidManifest.xml'
            java.srcDirs = ['src/main/java', 'src/main/aidl']
            resources.srcDirs = ['src/main/java', 'src/main/aidl']
            aidl.srcDirs = ['src/main/aidl']
            res.srcDirs = ['src/main/res']
            assets.srcDirs = ['src/main/assets']
            jni.srcDirs = ['src/main/jni', 'src/main/native']
            jniLibs.srcDirs 'src/main/jniLibs'
        }
    }

}

(2) Create CMakeLists.txt in the same level directory as build

cmake_minimum_required(VERSION 3.4.1)
#添加子目录, 调用子目录中的CMakeLists.txt
set(JNI_PATH ${
    
    CMAKE_CURRENT_SOURCE_DIR}/src/main/jni)
add_subdirectory(${
    
    JNI_PATH})

(3) Create CMakeLists.txt in src/main jni to generate so library

cmake_minimum_required(VERSION 3.4.1)
。。。。

Guess you like

Origin blog.csdn.net/weixin_41477306/article/details/107800170