最近做项目,集成的算法需要编译成so库给客户使用,在编译过程中遇到一些问题,下面先说下我的配置:
apply plugin: 'com.android.library'
android {
compileSdkVersion 27
defaultConfig {
minSdkVersion 23
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk{
abiFilters 'armeabi-v7a','arm64-v8a','armeabi'
}
externalNativeBuild {
cmake {
// cppFlags "-frtti -fexceptions"
cppFlags "-std=c++11 -frtti -fexceptions"
// arguments "-DANDROID_TOOLCHAIN=gcc"
// arguments "-DANDROID_ABI=arm64-v8a"
// arguments "-DANDROID_ABI=armeabi-v7a"
// arguments "-DCMAKE_BUILD_TYPE=Release"
}
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets.main{
//设置opencv的native库路径,用于加载opencv_java3
jniLibs.srcDir '../OpenCV-android-sdk/sdk/native/libs'
jni.srcDirs = [] //disable automatic ndk-build call
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(':openCVLibrary310')
}
发现编译有时候会根据(有时候不会出现三个,只在armeabi-v7a下有)
ndk{
abiFilters 'armeabi-v7a','arm64-v8a','armeabi'
}
而出现三个abiFilters 'armeabi-v7a','arm64-v8a','armeabi'
目录下有so,然后拷贝到其他项目运用时候
32位的手机可以正常跑,但64位的总是报错:
dlopen failed: "/data/app/com.example.lammy.transferinterface-IO3lOUc-19oaBjCNmDxA-A
==/lib/arm64/libtransfer.so" is 32-bit instead of 64-bit
报错原因很容易找到,加载arm64-v8a说是用32位的库代替了64位的,可是明明自己生的so库,后来将调用so库里加上:
ndk{
abiFilters 'armeabi-v7a'
}
让它只加载32位的,则64位和32位手机都可以跑了,但并没有完美解决,后面在编译库的moudle的gradle里添加
externalNativeBuild {
cmake {
// cppFlags "-frtti -fexceptions"
cppFlags "-std=c++11 -frtti -fexceptions"
// arguments "-DANDROID_TOOLCHAIN=gcc"
arguments "-DANDROID_ABI=arm64-v8a"
// arguments "-DANDROID_ABI=armeabi-v7a"
// arguments "-DCMAKE_BUILD_TYPE=Release"
}
}
代码,位置对应与上面的完整gradle来看,只需要打开注释。
cppFlags "-std=c++11 -frtti -fexceptions"
表示是使用c++11来编译,这里是为了解决在编译c++文件时,一些参数,如错误:
error: use of undeclared identifier 'nullptr' uchar* lut_ptr = nullptr;
arguments 则指明了编译的库的位数,这里使用arguments "-DANDROID_ABI=arm64-v8a"
编译出来的so库,才是真的64位的,如果要编译32位的,则需要修改arguments "-DANDROID_ABI=armeabi-v7a"
这样可以编译出不同的cpu的so库了。