Android studio关于Cmake的使用(第三章·引用第三方库文件)

 

目录

关于引用so库的方式

1 引用代JNI接口的so文件

1.1 生成一个包含jni接口的so

1.2 使用包含jni接口的so

2 引用纯净的通用so

2.1 构建支持C/C++的工程。

2.3 配置CmakeList.txt信息。

2.4 配置gradle

2.5 验收

2.6 调用

3. 交流与链接


关于引用so库的方式

1 引用代JNI接口的so文件

根据字面意思来说,就是这个.so文件包含的有带jni接口的.cpp文件。这个so是怎么生成的的呢?

1.1 生成一个包含jni接口的so

我们新建一个C++的Android studio工程(工程中自带.cpp文件和一个cmake.txt)。直接build apk,我们会在app-->build-->intermediates-->cmake-->obj里面有生成的好的so文件(存一下,下面有用)。当然既然是库文件,当然可以在其他工程中引用。

这个so既然包含的jni的.c文件,那我们在其他工程中是不是就不用写jni接口了?是的。但是又一个问题,看下工程中的.cpp文件。

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_heima_jniso_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

Jni接口的组成是 包名_类名_方法名。同样的,我们在使用这个.cpp或者使用这个.cpp编译成的so的时候,java端的引用,仍旧需要整个工程包名跟这个接口cpp一致。

1.2 使用包含jni接口的so

允许我偷懒一下,在工程上进行修改。这样做的目的是,工程的 包名_(引用jni接口的java)类名_方法名,都与so中的jni接口对应,这点很重要。

首先把module级别(app目录下)的build.gradle的cmake注释掉,因为直接调用jni的so不需要配置cmake脚本。然后加入so文件的引用引用路径。

android {

    //...

    sourceSets {
        main {
            // 引用的so库路径,默认是app/lib
            jniLibs.srcDirs = ['/JniSo']
        }
    }


    /*引用jni格式so不需要cmake文件*/
//    externalNativeBuild {
//        cmake {
//            path "CMakeLists.txt"
//        }
//    }

}

接着把刚才生成好的so文件粘贴到目标路径下。

最后,如果编译通过,检查生成的apk文件是否包含目标so,如果存在,表示引用包含jni接口的so成功。

2 引用纯净的通用so

上面介绍了引用包含jni接口的so文件,姑且就把不包含jni接口的so文件成为纯净的so文件。

关于如何通过Android studio的Cmake文件构建库文件在上篇文章已经说明,生成纯净的so文件可以点击下面的传送门回顾下,这里就不在啰嗦了。本篇主要介绍如何使用已经建好的库文件(包括动态和静态库文件)。这里以引用.so为例子

Android Studio使用CMAKE编译.so/.a

不罗嗦了,直接上干货。


2.1 构建支持C/C++的工程。

过程略。主要是生成带cmake脚本的包含c++的工程。

2.2 添加纯净的.so/.a。

把我们上篇博文已经构建好的库加入工程(注意路径)。我加入的位置与app同一个父级目录。(请忽略我生成库文件的名字。。。)

2.3 配置CmakeList.txt信息。

与创建库文件一样在add_library()中第一个参数为库的名字,第二个参数SHARE表示动态库so,STATIC表示静态库.a。

set_target_properties()是用来链接你的库文件,与add_library()配套使用,第一个参数为库名字,最后一个参数代表文件路径。

target_include_directories() 第一个参数为当前工程新建的总库文件名,用PRIVATE隔开,后面的参数为需要链接的第三方库的头文件。

直接附上代码以及详细的注释,相信大家都可以很快清楚cmake脚本语言的含义。

cmake_minimum_required(VERSION 3.4.1)

set(CMAKE_VERBOSE_MAKEFILE on)
# set()用来设置一个路径全局变量 distribution_DIR
set(distribution_DIR ${CMAKE_SOURCE_DIR}/../libBuild)

#创建总的库native-lib并链接一个.c文件,可以直接引用第三方库的头文件
add_library(native-lib SHARED
            ${CMAKE_SOURCE_DIR}/src/main/cpp/native-lib.c)
#链接第三方库的头文件
target_include_directories(native-lib PRIVATE
                           ${distribution_DIR}/one/include
                           ${distribution_DIR}/two/include)

# 创建一个静态库 lib_one 直接引用lib_a.a
add_library(lib_a STATIC IMPORTED)
set_target_properties(lib_a PROPERTIES IMPORTED_LOCATION
    ${distribution_DIR}/one/lib/${ANDROID_ABI}/liblib_a.a)

# 创建一个动态库 lib_two 直接引用lib_so.so
add_library(lib_so SHARED IMPORTED)
set_target_properties(lib_so PROPERTIES IMPORTED_LOCATION
    ${distribution_DIR}/two/lib/${ANDROID_ABI}/liblib_so.so)


find_library( log-lib
              log )

#把所有库文件都引入工程
target_link_libraries(
                       native-lib
                       lib_a
                       lib_so
                       ${log-lib} )

2.4 配置gradle

一定要注意module 级gradle的配置,不要忘了加入你的lib的路径。

android{

sourceSets {

    main {
        // let gradle pack the shared library into apk
        jniLibs.srcDirs = ['../libBuild/two/lib']
    }
}

}

2.5 验收

然后build一下工程,编译通过的话,OK,这些库文件就全部导入成功了。

下面可以验证一下so库是否何如app,首先build apk,然后apk文件打开视图,看lib文件夹下是否已经有你需要的so。

2.6 调用

下面关于带头文件的so/.a如何使用就十分简单了。

进入你cpp文件夹下的native-lib.c,include一下,你会发现这些与库文件配套的头文件自动弹出了,这就代表引用成功了,剩下来该干什么就干什么吧,啊哈~

3. 交流与链接

相信以上代码可以解决各位Android studio使用CMAKE引用第三方库遇上的大部分问题,如果接下来有时间,我会仔细研究一下cmake配置脚本,简单的处理一下语法问题。

我的文章更倾向与代码与注释的结合,文字介绍可能相对较少,方便大家直接copy与研究,如果文章有什么看不懂或者的地方,欢迎大家指教与讨论。

GitHub传送门

猜你喜欢

转载自blog.csdn.net/ma598214297/article/details/78387847