您当前的位置:首页 > 计算机 > 软件应用 > 开发(IDE)

关于NDK

时间:02-10来源:作者:点击数:

libc++_shared.so

在目前ndk的最新版本25.1.8937393中有4个libc++_shared.so,用Everything搜索结果如下:

在这里插入图片描述

可以看到,大小最小的有4M多。

对于libc++库,官方介绍在此,摘取一些片段如下:

LLVM 的 libc++ 是 C++ 标准库,自 Lollipop 以来 Android 操作系统便一直使用该库,并且从 NDK r18 开始成为 NDK 中唯一可用的 STL。

libc++ 的共享库为 libc++_shared.so,静态库为 libc++_static.a。通常情况下,构建系统将根据用户需要对这些库的使用和打包进行处理。

注意:libc++ 不是系统库。如果您使用 libc++_shared.so,就必须将该库添加到您的应用中。如果您使用 Gradle 构建应用,此步骤会自动完成。

接下来我们来验证一下最后一句话:如果您使用 Gradle 构建应用,此步骤会自动完成。

使用Android Studio的向导创建一个Native C++项目,自动创建的mative-lib.cpp文件如下:

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_cn_dazhou_hello_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

然后运行到模拟器,然后执行:构建 > Analyze Apk…,然后选择我们的app-debug.apk进行分析,如下:

在这里插入图片描述

如上图所示,产生的libhello.so大小为114.5KB。这里我们看不到libc++_shared.so,这是因为CMake构建工具默认使用c++_static进行编译的,也就是说会把用到的libc++_shared.so中的相关内容编译到libhello.so中,注意,只是编译用到的相关内容而已,这也是为什么libhello.so只有114.5KB,而libc++_shared.so有4M以上,我们可以配置CMake不使用c++_static,而使用c++_shared,如下:

plugins {
    ...
}

android {

    ...
    
    defaultConfig {
        applicationId "cn.dazhou.hello"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                arguments "-DANDROID_STL=c++_shared"
                cppFlags '-std=c++17'
            }
        }
    }

    externalNativeBuild {
        cmake {
            path file('src/main/cpp/CMakeLists.txt')
            version '3.18.1'
        }
    }

    ...
}

dependencies {
	...
}

关于cmake的更多参数在此

这个参数配置的写法我是参考的是这个

再次运行app,然后再查看apk的分析,如下:

在这里插入图片描述

如上图所示,此时就能看到libc++_shared.so了,大小为370.3KB,而libhello.so的大小只有17.3KB。

如果应用包括多个共享库,应使用libc++_shared.so,比如多个Android库有依赖关系,每个库都使用到了libc++,则应该使用c++_shared的方式编译,这样libc++_shared.so的内容就不会被重复打包到多个so中了。多个库中的libc++_shared.so最好保持使用同一个版本,因为最终打包apk时只会选择其中一个libc++_shared.so打包到apk中。

在 Android 系统中,NDK 使用的 libc++ 与操作系统的 libc++ 是不同的(也就是说Android系统本身内部就已经有libc++的实现了)。如此一来,即使应用以旧版 Android 为目标平台,NDK 用户也能获得最新的 libc++ 功能和 bug 修复。需要权衡的是,如果使用 libc++_shared.so,就必须将该库添加到您的应用中。如果使用 Gradle 构建应用,此步骤会自动完成。 早期使用ndk-build进行编译的时候,是不会自动使用 libc++_shared.so的,则默认使用的是系统内部自带的libc++库,比如该系统自带的libc++的版本是C++11,而我们写的C++代码使用到了C++17,则此时运行就会报找不到函数实现,所以需要使用ndk中支持c++17版本的libc++_shared.so实现,如果是用ndk-build编译的就需要指定添加该so,如果是使用gradle编译,则会自动使用对应的so,无需要手动设置。

使用特定版本的NDK

在以前比较旧版本的Android Studio中,是在local.properties指定NDK路径的,而较新版本的Android Studio已经看不到NDK路径的设置了,这是因为在发布之前,每个AGP(Android Gradle Plugin) 版本都使用当时最新的稳定 NDK 版本进行了全面测试。对于AGP版本 3.6 及更高版本,如果您未在build.gradle文件中指定 NDK 版本,则默认的 NDK 版本将用于构建您的项目。默认的 NDK 版本记录在AGP发行说明中。当前默认的 NDK 版本如下表所列:

Android Studio/Gradle 插件版本 对应的默认 NDK 版本
7.3 23.1.7779620
7.0 21.4.7075529
4.2 21.4.7075529
4.1 21.1.6352462
4.0 21.0.6113669
3.6 20.0.5594570
3.5或更低 无默认

如果需要使用特定的NDK版本,则可以在app的gradle文件中进行配置,如下:

android {
    ndkVersion "major.minor.build" // e.g.,  ndkVersion "21.3.6528147"
}

其实不同的版本的AGP有不同的设置NDK版本的方式,官网链接在此

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门