Android ABI

概念

不同的 Android 设备使用不同的 CPU,而不同的 CPU 支持不同的指令集。CPU 与指令集的每种组合都有专属的应用二进制接口 (ABI)。ABI 包含以下信息:

  • 可使用的 CPU 指令集(和扩展指令集)。
  • 运行时内存存储和加载的字节顺序。Android 始终是 little-endian。
  • 在应用和系统之间传递数据的规范(包括对齐限制),以及系统调用函数时如何使用堆栈和寄存器。
  • 可执行二进制文件(例如程序和共享库)的格式,以及它们支持的内容类型。Android 始终使用 ELF。如需了解详情,请参阅 ELF System V 应用二进制接口
  • 如何重整 C++ 名称。如需了解详情,请参阅 Generic/Itanium C++ ABI。

本页列举了 NDK 支持的 ABI,并且介绍了每个 ABI 的运行原理。

ABI 还可以指平台支持的原生 API。如需影响 32 位系统的此类 ABI 问题列表,请参阅 32 位 ABI 错误。

支持的 ABI

armeabi-v7a

此 ABI 适用于基于 32 位 ARM 的 CPU。Android 变体包含 Thumb-2 和 VFP 硬件浮点指令(具体而言就是 VFPv3-D16),其中包含 16 个专用 64 位浮点寄存器。

默认情况下,NDK 构建系统会生成 Thumb-2 代码,除非您在 Android.mk 中针对 ndk-build 使用 LOCAL_ARM_MODE,或在配置 CMake 时使用 ANDROID_ARM_MODE。
包括高级 SIMD (Neon) 和 VFPv3-D32 在内的其他扩展程序都是可选的。如需了解详情,请参阅 Neon 支持。
armeabi-v7a ABI 使用 -mfloat-abi=softfp 来强制实施以下规则:虽然系统可以执行浮点代码,但编译器在调用函数时必须传递整数寄存器中的所有 float 值以及整数寄存器对中的所有 double 值。

arm64-v8a

此 ABI 适用于基于 ARMv8-A 的 CPU,支持 64 位 AArch64 架构。它包含高级 SIMD (Neon) 架构扩展指令集。

x86_64

此 ABI 适用于支持通常称为“x86-64”的指令集的 CPU。它支持 GCC 通常使用以下编译器标志生成的指令:

-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel

为特定 ABI 生成代码

默认情况下,Gradle(无论是通过 Android Studio 使用,还是从命令行使用)会针对所有非弃用 ABI 进行构建。要限制应用支持的 ABI 集,请使用 abiFilters。例如,要仅针对 64 位 ABI 进行构建,请在 build.gradle 中设置以下配置:

android {
    defaultConfig {
        ndk {
            abiFilters 'arm64-v8a', 'x86_64'
        }
    }
}

构建系统的默认行为是将每个 ABI 的二进制文件包括在单个 APK(也称为胖 APK)内。与仅包含单个 ABI 的二进制文件的 APK 相比,胖 APK 要大得多;要权衡的是兼容性更广,但 APK 更大。强烈建议您利用 app bundle 和 APK 拆分减小 APK 的大小,同时仍保持最大限度的设备兼容性。

在安装时,软件包管理器只解压缩最适合目标设备的机器代码。如需了解详情,请参阅安装时自动解压缩原生代码。

Android 平台上的 ABI 管理

本部分详细说明了 Android 平台如何管理 APK 中的原生代码。

应用软件包中的原生代码

Play 商店和软件包管理器都希望能在 APK 中符合以下格式的文件路径上找到 NDK 生成的库:

/lib/<abi>/lib<name>.so

其中, 是支持的 ABI 下列出的 ABI 名称之一, 是您为 Android.mk 文件中的 LOCAL_MODULE 变量定义库时使用的库名称。由于 APK 文件只是 zip 文件,因此打开它们并确认共享原生库位于该位于的位置很简单。
如果系统在预期位置找不到原生共享库,便无法使用它们。在这种情况下,应用本身必须复制这些库,然后执行 dlopen()。

在胖 APK 中,每个库位于名称与相应 ABI 匹配的目录下。例如,胖 APK 可能包含:

/lib/armeabi/libfoo.so
/lib/armeabi-v7a/libfoo.so
/lib/arm64-v8a/libfoo.so
/lib/x86/libfoo.so
/lib/x86_64/libfoo.so

注意:搭载 4.0.3 或更早版本、基于 ARMv7 的 Android 设备从 armeabi 目录(而非 armeabi-v7a 目录,如果两个目录都存在)安装原生库。这是因为在 APK 中,/lib/armeabi/ 在 /lib/armeabi-v7a/ 后面。从 4.0.4 开始,此问题已修复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学知识拯救世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值