CMake方式调用第三方so
- 背景
- CMake工程配置
- 工程配置
- 配置CMakeLists.txt
- 配置build.gradle
- 调用第三方so中的方法
 
背景
最近一个项目是对接自研团队的个so库,因为之前都是用ndk来编译自己的so库,一直没有问题,但是用到这个自研的的so库一直有问题,调用不了里面的方法;原因就是:第三方提供的so库以及头文件都没有没有引入jni.h头文件。所以我们在导入第三方so库以及头文件的时候需要手动的将其关联到自己的so库中,关联成功后就可以在native库中include进第三方头文件,引进头文件成功后就可以在自定义的JNI接口中对第三方头文件中内容进行调用。
所以就尝试用CMake的方式来加载。
 建议大家还是用CMake的方式来进行JNI开发,因为CMake是跨平台的构建工具,对JNI开发来说比较明显的优点就是:1,编写c代码有提示;2,自动搜索正在构建的软件可能需要的程序、库和头文件的能力;3,能够为自动生成的文件创建复杂的自定义命令;其他的高级特性可自行搜索;
CMake工程配置
工程配置
1,android studio新建个新工程,不过多说明了;
 2,新建java文件testJni.java,随便哪个目录
    private native int sayHello(String text);
生成.h文件,可用参考 JNI生成so,然后把.h文件拷贝到jni(自己创建)目录下,如图:
 
新增文件夹,用来存放要导入的第三方so库以及头文件
第三方so库:放在src/main/libs/${ANDROID_ABI}(对应的CPU架构)/你的第三方so库
 第三方头文件:放在src/main/jni/你的第三方头文件
 如图:
 
注意以下几点:
 1)libs、CPU对应的架构文件夹(如上图的arm64-v8a)、jin都是我自己创建的;
2)CPU对应的架构文件夹可以根据自己需要来声明,因为提供给我的第三方so库只支持arm64-v8a,所以这里我只创建了arm64-v8a文件夹,通常来说,如果第三方支持什么CPU架构,就创建对应的架构文件夹(armeabi-v7a、arm64-v8a、x86、x84_64),然后把对应的so库放到对应的架构文件夹中;
3)这里的第三方so库以及头文件的存放位置只是我自己的习惯,并不是一定要按我这样放,你可以定义自己的存放路径,但是这个路径你要记住,在后面配置 CMakeLists.txt 中会用到。
配置CMakeLists.txt
app目录下新建空文件CMakeLists.txt
 
修改CMakeLists.txt,关联第三方头文件到native so,配置好第三方so库以及头文件导入的路径
#指定CMake构建本地库时所需的最小版本
cmake_minimum_required(VERSION 3.18.1)
# 指定编译出来的so库的存放位置,方便取用给其他开发者,如果指定到jniLibs下需要在build.gradle中配置编译优先解决冲突问题。
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI})
set(LIB_DIR "${CMAKE_SOURCE_DIR}/src/main/libs") # 第三方库的存放路径,命名为LIB_DIR,下面会用到
file(GLOB source src/main/jni/testjni.cpp)
add_library( # Sets the name of the library. 将资源文件生成动态链接库(so文件)的库名称(文件名称:“lib" +设置的名称)
        test_jni
        # Sets the library as a shared library.
        SHARED
        # Provides a relative path to your source file(s).资源文件(C或C++)的相对位置
        ${source}
        )
target_include_directories(test_jni
        PRIVATE
        ${PROJECT_SOURCE_DIR}/src/main/jni)
add_library(fronted
        SHARED IMPORTED)
set_target_properties(fronted
        PROPERTIES IMPORTED_LOCATION
        ${LIB_DIR}/${ANDROID_ABI}/libfronted.so) # 指定第三方库的位置、链接
find_library( # Sets the name of the path variable.
        log-lib
        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log )
target_link_libraries( # Specifies the target library.将所有的add_library中的库链接起来,有多少个add_library成的库就将其添加到这里
        test_jni  #这个和add_library中的指定的so库名称一致
        fronted
        #                        lib-add
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib} )
第三方so名称是libfronted.so,注意make文件中的用法及定义,里面有相应的注释,需要注意的地方如图
 
 
配置build.gradle
注意是app下的build.gradle
android {
    compileSdk 32
    defaultConfig {
        applicationId "com.zeekr.zeekrmake"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild{
            cmake{
                cppFlags ""// 设置c++标准为默认
                abiFilters "arm64-v8a"
            }
        }
        ndk {// 可以不配置
            moduleName "test_jni" // ndk模块名字
            abiFilters "arm64-v8a"// 不配置的话,默认生成所有平台的so
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    externalNativeBuild{
        cmake{
            // version '3.10.2'
            path "CMakeLists.txt"// 指定CMake文件的位置
        }
    }
    buildFeatures {
        viewBinding true
    }
}

 
 配置完成后make project;
调用第三方so中的方法
没有错误,说明配置成功,就可以引入自研so库中的.h文件了,然后调用其中的方法了;
 
 make project就可用生成so库了,目录在makefile文件中定义有;
 
这篇文章就介绍到这里,喜欢的点赞求关注。








![[Vivado那些事儿]将自定义 IP (HDL)添加到 Vivado 模块设计(Block Design)](https://img-blog.csdnimg.cn/img_convert/3d5903d64f515403586b11db28e93c63.png)










![[Datawhale][CS224W]图机器学习(二)](https://img-blog.csdnimg.cn/img_convert/c5fffac80ff9c29f4fedbb86c97d6f68.png)