android基于cmakelist构建so库及使用
关键点
构建及使用so文件,主要包括以下三点
- abifilter
- cmakelist
- build.gradle
目标
- 在一个工程中构建单独的so库
- 在另外一个工程中c++能够正常调用
构建so
此步骤主要是构建出单独的so文件,供其他工程使用
- 新建android native c++工程,自带了jni,cmakelist等,省的自己添加了;
- 修改build.gradle选项,主要是修改c++编译选项及abifilter;
- 添加源文件及头头文件(功能实现);
- 修改cmakelist.txt(控制编译及生成);
下面详细介绍下,步骤2及4;
首先需要修改build.gradle,主要是添加编译选项,及abiFilters,以及相关路径设置,参考文件注释
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.1"
defaultConfig {
// 省略...
externalNativeBuild {
cmake {
cppFlags "-std=c++17"
abiFilters "x86_64","x86" // 控制编译出哪些abi文件,使用者需要和提供者保持一致
}
}
}
buildTypes {
release {
// 省略...
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt" //cmakelist文件路径
version "3.10.2"
}
}
}
// 省略...
源文件及头文件创建省略,本次测试源端目录结构如下
cmakelist设置
cmake_minimum_required(VERSION 3.4.1)
# 源工程相关构建脚本未修改
add_library( # Sets the name of the library.
native-lib
SHARED
native-lib.cpp)
# 新增构建脚本,${CMAKE_SOURCE_DIR}是一个cmake变量,其路径是cmakelist.txt所在路径
include_directories(${CMAKE_SOURCE_DIR})
add_library( # Sets the name of the library.
ShraredLibTest # 新增模块名称
SHARED # 模式,static/shared
SharedLibTest.cpp) #源文件路径
# 查找系统库log,并将其路径赋值给log-lib
find_library( # Sets the name of the path variable.
log-lib
log)
#项目自带的库
target_link_libraries( # Specifies the target library.
native-lib
${log-lib})
# 我们要构建的库,注意依赖
target_link_libraries( # Specifies the target library.
ShraredLibTest
${log-lib})
到此,构建so的相关工作已经完成,一切正常的话,make后会在类似如下路径LibTest\app\build\intermediates\transforms\mergeJniLibs\debug\0\lib\x86中生成两个库,一个libnative-lib.so(项目自带的,我们不用);另外一个是libShraredLibTest.so,我们目标so
注意路径中x86和abifilters有关,通常情况下设置了几个,会有几个类似目录,生成针对不同平台的so,此次使用模拟器,故构建了x86。
使用so
主要包括以下步骤
- 拷贝文件(so及头文件)
- 修改build.gradle
- 修改代码
- 修改cmakelist.txt
拷贝文件
拷贝文件需要注意路径,so文件的路径,在gradle中会用到,以便把该so编译的时候打包进apk,cmakelist也会用到;头文件的路径cmakelist也会用到
结构如下,工程构建方法同上,native c++的工程,相关jni,cmakelist文件已经自动生成,本次在natvie-lib.cpp中直接调用上面的so中的方法,无需增加新的jni接口
修改build.gradle
见文件注释
apply plugin: 'com.android.application'
android {
//...
cmake {
cppFlags "-std=c++17"
abiFilters "x86_64","x86" // 控制编译出哪些abi文件,使用者需要和提供者保持一致
}
}
}
//...
//设置libs文件路径,如果放置的是其他路径,需要修改成对应的相对路径
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
cmakelist修改
见注释
cmake_minimum_required(VERSION 3.4.1)
# 定义一个变量,表示根路径
set(ROOT_DIR ${CMAKE_SOURCE_DIR}/../../../../)
# 项目自带文件,native-lib.cpp中会调用我们的so
add_library( # Sets the name of the library.
native-lib
SHARED
native-lib.cpp)
// 设置头文件路径,根据头文件放置位置修改
include_directories(${CMAKE_SOURCE_DIR})
// 引入so库,注意方式是IMPORTED
add_library( # Sets the name of the library.
ShraredLibTest
SHARED
IMPORTED)
// 设置so库文件的路径
set_target_properties(ShraredLibTest
PROPERTIES IMPORTED_LOCATION
${ROOT_DIR}/app/libs/${ANDROID_ABI}/libShraredLibTest.so
)
find_library( # Sets the name of the path variable.
log-lib
log)
// 修改链接依赖
target_link_libraries( # Specifies the target library.
native-lib
ShraredLibTest
${log-lib})
基本上就是这么个步骤,可以参考修改
运行效果如下
环境
NDK 20
Cmake 3.10
Android studio 3.4