Android中CMake的使用之四调用第三方库的实战

继续上回中第三方库的调用,在实际的工程中要使用一个算法的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,这个在向上写相对路径时,无法使用,一定得记清。
更悲催的是,还把库的位置书写路径,写到了其它的配置项内,大错特错了。

用的还是少,做得还是不多,这才是这些错误的根本。

猜你喜欢

转载自blog.csdn.net/fpcc/article/details/72820934