Android 64位 ABI(x86_64) 的原生库(.so 文件)不支持 16KB 内存页大小的问题

问题:Memory page size: Does not support 16 KB

在这里插入图片描述

Google Play 要求所有 64 位原生库(.so)必须支持 16KB 页面大小,否则会拒绝上架。这是从 Android 12(API 31)开始引入的限制。

  • Android 从 Android 12(API 31)开始,对 64位设备 引入了 16KB 内存页大小 的优化。
  • 为了提高性能和内存效率,系统在某些场景下使用 16KB 页面(而不是传统的 4KB 页面)。
  • 所有原生库(.so)必须 兼容 16KB 页面大小,否则会导致:
    • 启动失败
    • 运行时崩溃
    • 被 Google Play 拒绝发布

解决方法:

  1. 删除 local.properties 中的 ndk.dir;在 build.gradle 中设置 android.ndkVersion;
  2. 使用 NDK r23 或更高版本;
ndkVersion "23.1.7779620" // 支持 16KB 内存页面大小(NDK最低23)
  1. 在 CMakeLists.txt 中配置(-Wl,-z,max-page-size=16384)如下:

写法一:影响目标作用域(荐);

# 【新增】添加链接器参数支持 16KB 页面大小
set_target_properties(smartho_algo PROPERTIES
        LINK_FLAGS "
        -Wl,-z,max-page-size=16384 
        -Wl,--warn-common 
        -Wl,--no-fatal-warnings"
)

写法二:影响全局作用域;

# 强制使用 16KB 页面对齐
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")

# 启用位置无关代码(PIC),避免旧 ABI 行为影响对齐
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

全局变量 说明:

  • CMAKE_SHARED_LINKER_FLAGS:影响当前目录及所有子目录中的所有共享库目标;
  • CMAKE_EXE_LINKER_FLAGS - 影响可执行文件
  • CMAKE_STATIC_LINKER_FLAGS - 影响静态库

验证:

要验证一个 .so(共享库)是否支持 16KB 内存页面大小(Large Page Support),你需要检查其 ELF 格式中的段对齐属性(p_align)。

使用 Android NDK 自带的 readelf 检查 p_align

1、在 Windows NDK 中,使用 llvm-readelf 命令:

具体位置参考:D:\Soft\Android\SDK\ndk\23.1.7779620\toolchains\llvm\prebuilt\windows-x86_64\bin\llvm-readelf.exe

2、.so编译后,验证:

llvm-readelf -l libsmartho_algo.so

3、应该能看到(0x4000 的值为 16384):

LOAD ... Align 0x4000   
LOAD ... Align 0x4000   

不支持的情况:
在这里插入图片描述
支持的情况:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

唐诺

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

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

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

打赏作者

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

抵扣说明:

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

余额充值