在过去的几周里,我根据 Xlog 和 Loagan 的设计思路,使用 Rust 写了一个移动端的跨平台日志库EZLog。
在我实现这个库的过程中,查阅了大量的问答和博客。因为这些开发者的分享,节省了我大量的时间。所以我把我的经历也分享出来。
如果以下任何一个点你感兴趣,不要划走。
当下(2022)Rust 在移动端的开发体验如何
没有 Java/Kotlin 代码,不使用 AndroidStudio 和 Gradle, 秒级编译并打包 Apk 运行
Rust 编译静态库打包到 XCFramework, 发布 Cocoapods
起因
22 年初,我有一个游戏需求,要在 android 上实现匀速的贝塞尔曲线路径移动。依赖 kurbo写了一个生成贝塞尔曲线 LUT 的命令行工具,体验很好。于是想尝试一下,发挥 Rust 的优势,在移动端写一个对性能有要求的开源库,第一个想到的就是日志。
可行性调查
大型公司在移动端使用 Rust
Google 在 2021 年将 Rust 引入 Android Rust in the Android platform
Mozilla 使用 Rust 编写跨平台应用服务组件Firefox Application Services
飞书客户端非 UI 部分使用 Rust 跨平台实现
个人开发者在移动端的尝试 Rust 的案例
Rust & cross-platform mobile development
RustDesk 远程桌面应用
深度探索:前端中的后端
Publish game on Android with Macroquad
Rust on iOS and Mac Catalyst: A Simple, Updated Guide
更多的案例收录,可以参看这篇Rust 移动开发与跨平台模式探究。 从以上的例子来看,大概率是可行的,还要对具体的需求进行验证。
项目简述
主要功能
使用 mmap 做文件映射
认证加密
zlib 压缩
日志回捞
日志清理
命令行解析工具
可行性验证
先查找主要功能是否有对应的 Rust 开源实现。
memmap2
aead
flate2
开源社区早已实现好了:) 复制开源库中的示例,借助android-ndk-rs。在 android 真机运行,查看日志输出,符合预期。 项目中使用android ndk rs的例子,可以查看examples/android_preview
编译成APK并安装运行不到5秒
cargo apk run -p ezlog_android_preview
Compiling ezlog v0.1.2 (ezlog/ezlog-core)
Compiling ezlog_android_preview v0.1.0 (ezlog/examples/android_preview)
Finished dev [unoptimized + debuginfo] target(s) in 2.39s
'lib/arm64-v8a/libezlog_android_preview.so'...
Verifying alignment of ezlog/target/debug/apk/ezlog_android_preview.apk (4)...
49 AndroidManifest.xml (OK - compressed)
1020 lib/arm64-v8a/libezlog_android_preview.so (OK)
Verification succesful
Performing Incremental Install
Serving...
All files should be loaded. Notifying the device.
Success
Install command complete in 949 ms
Starting: Intent {
act=android.intent.action.MAIN cmp=rust.ezlog_android_preview/android.app.NativeActivity }
项目结构
├── android
│ ├── app # android 示例工程
│ └── lib-ezlog # EZLog android 库
├── examples # rust 示例
├── ezlog-cli # 命令行工具
├── ezlog-core # 核心库
├── ios
│ ├── EZLog # EZLog iOS 库
│ ├── demo # iOS 示例工程
│ └── framework # EZLog XCFramework
开发中碰到的问题及解决
iOS
iOS 端的开发流程为
Rust 编码
通过 cbindgen 生成头文件
编译多平台静态库
把静态库和头文件打包成 XCFramework,并依赖
实现 Swift 绑定
测试,发布
在对比了多种依赖静态库的方式之后,发现XCFramework对多平台的支持,更适合这个项目。更多 XCFramework 的相关资料可以看这几篇文章distributing universal ios frameworks as xcframeworks using cocoapods, Static libraries into XCFramework,From Rust To Swift。在项目中的构建使用,可以参看ios/b_ios.sh脚本。
Swift 与 C 的互相调用,很多概念需要了解。在被Unmanaged, @escaping,@convention,UnsafePointer,UnsafeBufferPointer, UnsafeMutableRawPointer 折磨许久之后,终于可以在 Swift 中拿到 Rust 的回调了。
Cocoapods 支持 XCFramework,尝试了 SPM,找不到符号的问题没有解决。暂时放一放。在花费了以天计的时间成本之后,终于在 Cocoapods 成功发布。
对比一下三个包管理工具的从注册到发布的时间成本,
精彩内容
发表评论