继续上回中第三方库的调用,在实际的工程中要使用一个算法的SO库(也提供了.a),然后就按上述的方法进行了调用。结果在这个过程中出现了一些新的问题。
首先,在调用的时候儿在CMakeLists.txt添加好相关的SO后:
add_library( # Sets the name of the library. XXX # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). IMPORTED)
编译时发现这样一个问题“XXX库得需要相关的native-lib库,没有生成..//..//mips64//native-lib的相关规则”之类的,去生成路径下查询,果然没有这个本地库,可要是把这个添加的库在CMakeLists.txt去除,就没有了问题。这个折腾了有一两个小时,后来突然明白,会不会是给的库中版本不全,然后就开始试。
算法给的库,只有四个版本,arm64-v8a,armeabi-v8a,x86,x86_64,在使用之三的生成的库中进行测试,去除了一个mips64相关的第三方库,果然报相关的错误,好。这就说明,只要控制好自己的版本生成,在编译过程中不生成上述四种以外的库就可以了。当然小于这四种也可以。
apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "com.example.fjf.testfacealgo" minSdkVersion 17 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { cppFlags "-std=c++11 -frtti -fexceptions" arguments "-DANDROID_STL=c++_static" } } ndk{ abiFilters "arm64-v8a", "armeabi-v7a" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } externalNativeBuild { cmake { path "CMakeLists.txt" } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.3.0' compile 'com.android.support.constraint:constraint-layout:1.0.2' testCompile 'junit:junit:4.12' }
重点是上面的红色的abiFilters部分,这里只生成了两种,果然就不再报这个错误了。但是又出现了下面这个错误
“nomember named 'to_string' in namespace 'std'”
也是醉了。用个STL还都不行了。这个也用了不少时间,因为这种错误很少,后来在STACKOVERFLOW中发现了端倪,有人说NDK中默认使用的是最小的STL库,于是就会产生这种现象,深以为是。于是从谷歌的官网上查到NDK中的配置,配合在STACKOVERFLOW上的解决方案,终于明白了怎么回事儿。
android {
...
defaultConfig {
...
// This block is different from the one you use to link Gradle
// to your CMake build script.
externalNativeBuild {
cmake {
...
// Use the following syntax when passing arguments to variables:
// arguments "-DVAR_NAME=VALUE"
// ------------------- ANSWER -------------------
arguments "-DANDROID_STL=c++_shared"
}
}
}
buildTypes {...}
// Use this block to link Gradle to your CMake build script.
externalNativeBuild {
cmake {...}
}
}
仍然是看红色部分,但是细节的可能看到这里的红色部分和上面更全的使用的不一样啊,这里用的C++_shared,而上面使用的c++_static,那就得看下面两个网页了:
Read these:
https://developer.android.com/ndk/guides/cmake.html#variables
https://developer.android.com/ndk/guides/cpp-support.htm
在ANDROID_STL选项中可以点击跳转到指定页面的说明:
名称 |
说明> |
功能 |
libstdc++(默认) |
默认最小系统 C++ 运行时库。 |
不适用 |
gabi++_static |
GAbi++ 运行时(静态)。 |
C++ 异常和 RTTI |
gabi++_shared |
GAbi++ 运行时(共享)。 |
C++ 异常和 RTTI |
stlport_static |
STLport 运行时(静态)。 |
C++ 异常和 RTTI;标准库 |
stlport_shared |
STLport 运行时(共享)。 |
C++ 异常和 RTTI;标准库 |
gnustl_static |
GNU STL(静态)。 |
C++ 异常和 RTTI;标准库 |
gnustl_shared |
GNU STL(共享)。 |
C++ 异常和 RTTI;标准库 |
c++_static |
LLVM libc++ 运行时(静态)。 |
C++ 异常和 RTTI;标准库 |
c++_shared |
LLVM libc++ 运行时(共享)。 |
C++ 异常和 RTTI;标准库 |
都安排好了,再编译,还是报SO依赖的问题,结果在走查后发现了一个更悲催的问题,库的名字写错了,这种低级的错误,导致了一系列的问题啊。
同样,在添加库的路径时,也遇到了在第三篇博客中遇到的各种问题,值得说明的是CMAKE_SOURCE_DIR,这个在向上写相对路径时,无法使用,一定得记清。
更悲催的是,还把库的位置书写路径,写到了其它的配置项内,大错特错了。
用的还是少,做得还是不多,这才是这些错误的根本。