我们在编写NDK时候,有时候需要依赖第三方so库,如ffmpeg。
如果这里配置的是多种架构:
externalNativeBuild {
cmake {
cppFlags ""
//生成.so库的目标平台
abiFilters 'armeabi','armeabi-v7a'
}
}
假如cmakeList.txt配置如下,则会生成 两个libless.so库,并分别存在
armeabi和 armeabi-v7 目录下。
cmake_minimum_required(VERSION 3.4.1)
#源码树的顶层路径。
set(distribution_DIR ${PROJECT_SOURCE_DIR}/src/main/jniLibs)
# 查看gradle Console 调试信息 PROJECT_SOURCE_DIR => E:/Codes/android_code/TPlayer/ffmpeg
message(STATUS "========> the PROJECT_SOURCE_DIR is : ${PROJECT_SOURCE_DIR}")
message(STATUS "========> the PROJECT_BINARY_DIR is : ${PROJECT_BINARY_DIR}")
message(STATUS "========> the cmakeList.txt PATH is : ${CMAKE_CURRENT_SOURCE_DIR}")
message(STATUS "========> distribution_DIR is : ${distribution_DIR}")
#判断编译器类型,如果是gcc编译器,则在编译选项中加入c++11支持
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
message(STATUS "optional:-std=c++11")
endif(CMAKE_COMPILER_IS_GNUCXX)
#支持-std=gnu++11
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
# 个人库
add_library( # Sets the name of the library.
less
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp
)
# 系统库
find_library( # Sets the name of the path variable.
log-lib
log )
find_library( # Sets the name of the path variable.
z-lib
z )
find_library( # Sets the name of the path variable.
android-lib
android )
# 第三方库
add_library(avcodec-57 SHARED IMPORTED)
set_target_properties(avcodec-57 PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/armeabi/libavcodec-57.so)
add_library(avfilter-6 SHARED IMPORTED)
set_target_properties(avfilter-6 PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/armeabi/libavfilter-6.so)
add_library(avformat-57 SHARED IMPORTED)
set_target_properties(avformat-57 PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/armeabi/libavformat-57.so)
add_library(avutil-55 SHARED IMPORTED)
set_target_properties(avutil-55 PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/armeabi/libavutil-55.so)
add_library(swresample-2 SHARED IMPORTED)
set_target_properties(swresample-2 PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/armeabi/libswresample-2.so)
add_library(swscale-4 SHARED IMPORTED)
set_target_properties(swscale-4 PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/armeabi/libswscale-4.so)
add_library(avdevice-57 SHARED IMPORTED)
set_target_properties(avdevice-57 PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/armeabi/libavdevice-57.so)
include_directories(${PROJECT_SOURCE_DIR}/src/main/jniLibs/include)
target_link_libraries(
less avcodec-57 avfilter-6 avformat-57 avutil-55 swresample-2 swscale-4 avdevice-57
${log-lib}
${z-lib}
${android-lib}
)
开发的时候,NDK虽然依赖其他的so,但是它只会生成我们自己的so并放在相应架构 的目录中,其他的so它不会管的也管不着。我们CmakeList.txt依赖的so库是可以放在任何地方的(D盘,F盘都行),但这里为了不用构建apk时候 重复拷贝 就直接放在了armeabi下,那么打包的时候就出现了上面的情景。
所以说: 平常建议 依赖第三方的so库 的架构 要和 我们自己构建的 so库 架构 一致 ,
要么都是只有一个armeabi,要么都是两个 armeabi和armeabi-v7
开发建议
armeabi 改为${ANDROID_ABI}来根据${ANDROID_ABI}选择依赖。
add_library(myjpeg SHARED IMPORTED)
set_target_properties(jpeg PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libjpeg.so)
${ANDROID_ABI}是根据gradle中声明的abiFilters来指定的。
apply plugin: 'com.android.library'
android {
compileSdkVersion 26
buildToolsVersion "26.0.0"
defaultConfig {
minSdkVersion 14
targetSdkVersion 14
versionCode 1
versionName "1.0"
externalNativeBuild {
cmake {
cppFlags ""
//生成.so库的目标平台
abiFilters 'armeabi','armeabi-v7'
}
}
}
buildTypes {
debug {
minifyEnabled false
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path 'CMakeLists.txt'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}