1. 项目概述
最近在开发一个Android应用时,遇到了16KB页面大小适配的问题,特别是针对腾讯Mars XLog库的适配。由于网上相关资料较少,我决定记录下完整的Windows环境下从XLog编译到16KB适配的全过程。本文将详细介绍环境搭建、编译步骤、16KB适配方案以及实际验证方法。
2. 环境准备
2.1 Python3安装
首先需要安装Python3环境,这是编译XLog的基础依赖。建议从Python官网下载最新稳定版本(当前为3.14.2):
- 访问Python官网下载页面
- 下载适合你系统的安装包(32位或64位)
- 安装时勾选"Add Python to PATH"选项
- 安装完成后,在命令行输入
python --version验证安装是否成功
注意:如果系统中有多个Python版本,建议使用虚拟环境管理不同项目的依赖。
2.2 NDK安装配置
XLog官方文档推荐使用NDK r20,但实际测试发现NDK r25也能正常工作。安装方式有两种:
方法一:从Android官网下载
- 访问Android NDK下载页面
- 选择适合的版本下载并解压
方法二:通过Android Studio安装
- 打开Android Studio
- 进入File > Settings > Appearance & Behavior > System Settings > Android SDK
- 选择SDK Tools标签页
- 勾选NDK并安装
安装完成后需要配置环境变量:
- 新建系统变量
NDK_ROOT,值为NDK安装路径(如D:\AndroidSDK\ndk\25.1.8937393) - 将
%NDK_ROOT%添加到PATH环境变量中 - 在命令行输入
ndk-build --version验证配置是否成功
2.3 CMake安装
CMake是跨平台的构建工具,XLog编译需要3.22.1或更高版本:
- 从CMake官网下载安装包
- 安装时选择"Add CMake to the system PATH for all users"
- 安装完成后,在命令行输入
cmake --version验证
2.4 Cygwin安装配置
由于XLog的编译脚本使用了一些Unix工具,在Windows上需要安装Cygwin:
- 从Cygwin官网下载setup-x86_64.exe
- 运行安装程序,选择"Install from Internet"
- 在镜像源选择界面,添加阿里云镜像源:
http://mirrors.aliyun.com/cygwin/ - 在包选择界面,搜索并选择以下包:
- make
- gcc-core
- gcc-g++
- gdb
- 完成安装后,将Cygwin的bin目录(如
C:\cygwin64\bin)添加到PATH环境变量
3. XLog编译过程
3.1 获取XLog源码
XLog是腾讯Mars框架的一部分,可以从GitHub获取源码:
bash复制git clone https://github.com/Tencent/mars.git
3.2 修改编译脚本
在编译前需要修改build_android.py脚本中的两个关键变量:
ANDROID_STL_FILE:指定不同CPU架构对应的STL库路径ANDROID_STRIP_FILE:指定strip工具路径,用于减小生成的so文件体积
对于NDK r25,修改示例如下:
python复制ANDROID_STRIP_FILE = NDK_ROOT + '/toolchains/llvm/prebuilt/%s/bin/llvm-strip'
ANDROID_STL_FILE = {
'armeabi-v7a': NDK_ROOT + '/toolchains/llvm/prebuilt/%s/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so',
'arm64-v8a': NDK_ROOT + '/toolchains/llvm/prebuilt/%s/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so',
'x86': NDK_ROOT + '/toolchains/llvm/prebuilt/%s/sysroot/usr/lib/i686-linux-android/libc++_shared.so',
'x86_64': NDK_ROOT + '/toolchains/llvm/prebuilt/%s/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so',
}
3.3 执行编译
- 打开命令行,进入mars/mars目录
- 执行编译命令:
bash复制python build_android.py
- 根据提示选择编译选项:
- 1:清理并完整编译Mars
- 2:增量编译Mars
- 3:仅编译XLog(推荐选择此项)
- 4:退出
编译完成后,生成的so文件位于:
mars/libraries/mars_xlog_sdk/libs/armeabi-v7amars/libraries/mars_xlog_sdk/libs/arm64-v8a
3.4 编译注意事项
- 路径问题:确保所有工具(Python、NDK、CMake、Cygwin)的路径都正确添加到环境变量
- 权限问题:如果遇到权限错误,尝试以管理员身份运行命令行
- 版本兼容性:不同版本的NDK可能会有细微差异,建议使用文档中提到的版本
- strip工具:NDK r19+使用统一的llvm-strip工具,路径为
NDK_ROOT/toolchains/llvm/prebuilt/windows-x86_64/bin/llvm-strip.exe
4. 16KB页面大小适配
4.1 16KB页面背景
Android 10引入了对16KB页面大小的支持,相比传统的4KB页面,16KB页面能:
- 减少TLB miss
- 提高内存访问效率
- 降低内存碎片化
但需要确保所有so文件都正确适配16KB对齐。
4.2 不同NDK版本的适配方案
4.2.1 NDK r28及更高版本
从NDK r28开始,默认编译为16KB对齐,无需额外配置。
4.2.2 NDK r27
在build.gradle中添加以下配置:
groovy复制android {
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
}
}
}
}
4.2.3 NDK r26及更低版本
需要在CMakeLists.txt中添加链接选项:
cmake复制target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384")
对于XLog项目,由于使用的是CMake 3.6,需要使用旧式语法:
cmake复制set_target_properties(${SELF_LIB_NAME}
PROPERTIES LINK_FLAGS "-Wl,-z,max-page-size=16384")
具体修改位置:
- 在
marsxlog的add_library后添加 - 在
marsstn的add_library后添加
4.3 适配原理
-Wl,-z,max-page-size=16384链接器选项的作用是:
- 告诉链接器使用16KB(16384字节)作为最大页面大小
- 确保生成的so文件中的段(segment)都按16KB对齐
- 为Android系统的16KB页面大小优化做准备
5. 验证与测试
5.1 使用LibChecker验证
- 从Google Play下载安装LibChecker应用
- 打开应用,找到你的应用
- 查看so文件信息,标有"16KB"标签的表示适配成功
5.2 手动检查
可以使用readelf工具检查so文件的对齐情况:
bash复制readelf -l your_library.so | grep -A 1 LOAD
输出中Align列的值为16384表示16KB对齐成功。
5.3 性能测试
适配16KB后,建议进行以下测试:
- 内存占用测试
- 启动速度测试
- 长时间运行稳定性测试
6. 常见问题与解决方案
6.1 编译失败问题
问题1:Python环境问题
- 现象:执行python命令报错
- 解决:确认Python已正确安装并添加到PATH
问题2:NDK路径问题
- 现象:编译时报找不到NDK
- 解决:检查NDK_ROOT环境变量是否正确设置
问题3:Cygwin工具缺失
- 现象:make或gcc命令找不到
- 解决:确认Cygwin已安装make、gcc等工具
6.2 16KB适配问题
问题1:旧版NDK适配无效
- 现象:添加链接选项后仍显示4KB
- 解决:升级到NDK r28或更高版本
问题2:兼容性问题
- 现象:在某些设备上崩溃
- 解决:确保所有依赖的so文件都适配16KB
6.3 性能问题
问题1:内存占用增加
- 现象:适配后内存使用量上升
- 解决:检查是否有不必要的段对齐,优化代码段和数据段
问题2:启动变慢
- 现象:应用启动时间变长
- 解决:减少so文件数量,合并小so文件
7. 优化建议
- 统一NDK版本:建议团队统一使用NDK r28或更高版本,简化配置
- CI/CD集成:将编译和适配流程集成到持续集成系统中
- 性能监控:建立性能基准,监控适配前后的关键指标变化
- 渐进式适配:可以先适配核心so文件,逐步扩展到全部
- 文档记录:详细记录适配过程和配置变更,方便后续维护
在实际项目中,我发现16KB适配虽然需要一些额外工作,但对于性能敏感型应用确实能带来可观的性能提升。特别是在内存访问频繁的场景下,TLB miss的减少可以显著提高运行效率。建议在项目早期就考虑16KB适配,避免后期大规模重构。