资讯动态

Android Soong 构建规则中的 Rust:从 rust_binary 到 rust_library 的完整指南(comprehensive-rust 实战)

发布时间:2026/9/11 19:00:41 来源:尧图企业网站定制
Android Soong 构建规则中的 Rust从 rust_binary 到 rust_library 的完整指南comprehensive-rust 实战【免费下载链接】comprehensive-rustThis is the Rust course used by the Android team at Google. It provides you the material to quickly teach Rust.项目地址: https://gitcode.com/GitHub_Trending/co/comprehensive-rust导读Android 的系统软件服务、库、驱动乃至固件如今都可以用 Rust 编写而这一切的构建基础是 Android 的 Soong 构建系统对 Rust 的深度支持。本文以 comprehensive-rust 课程的 Build Rules 章节为核心系统讲解 Soong 提供的 8 类 Rust 模块类型并结合仓库内的真实Android.bp与源码带你从零构建、推送并在模拟器中运行第一个 Rust 二进制再通过rust_library完成跨模块依赖组织。读完本文你将掌握在 AOSP 工程中声明 Rust 模块、配置依赖、规避动态链接问题以及用m/adb完成构建部署的完整技能。Soong 与 Android 的 Rust 支持为什么需要一套新构建规则Rust 在 Android 中并非“寄生”在既有语言之上而是作为一等公民被 SoongAndroid 的构建系统原生支持。Soong 通过一系列专用模块类型让 Rust 代码与 C/C、Java 代码在同一条构建流水线中协作。其核心动机可以归结为三点见原文档 Build Rules 的演讲备注Cargo 不适合多语言仓库Cargo 面向单一语言的包管理场景且需要从互联网下载包而 Android 是一个包含 C/C/Java/Rust 的巨型多语言代码库。合规与性能要求 crate 在树内in-treeAndroid 必须将第三方 crate 以源码形式放入仓库内部管理同时还要与 C/C/Java 代码互操作这正是 Soong 填补的空缺。与 Bazel 的渊源Soong 与 BazelBlaze 的开源版本google3 内部使用有诸多相似之处。可以理解为 Android 特有的、面向多语言大型仓库的构建方案。这些设计决定了 Android 上的 Rust 构建规则“长得像其他 Soong 规则”——这不是巧合而是有意为之让 Rust 的使用难度与 C 或 Java 对齐见 Rust Binaries 的演讲备注。Rust 模块类型一览Soong 支持的 8 类模块原文档给出了 Soong 支持的完整 Rust 模块类型清单模块类型说明rust_binary生成一个 Rust 可执行二进制。rust_library生成一个 Rust 库同时提供rlib与dylib两种变体。rust_ffi生成可被cc模块使用的 Rust C 库同时提供静态与共享两种变体。rust_proc_macro生成proc-macroRust 库功能上类似于编译器插件。rust_test生成使用标准 Rust 测试框架test harness的测试二进制。rust_fuzz生成基于libfuzzer的模糊测试fuzz二进制。rust_protobuf生成源码并产出为特定 protobuf 提供接口的 Rust 库。rust_bindgen生成源码并产出包含 C 库 Rust 绑定bindings的 Rust 库。这张表覆盖了从应用二进制到 FFI、从单元测试到模糊测试、从 protobuf 到 C 绑定生成的完整开发场景。原文档声明接下来重点讲解rust_binary和rust_library本文同样围绕这两个核心类型展开其余类型结合仓库实例逐一补充。实战一用 rust_binary 构建第一个 Android Rust 二进制编写模块定义与源码在一个 AOSP checkout 的根目录下创建如下两个文件。首先是hello_rust/Android.bp完整内容可在仓库中的 src/android/build-rules/binary/Android.bp 找到rust_binary { name: hello_rust, crate_name: hello_rust, srcs: [src/main.rs], }其次是hello_rust/src/main.rs源码见 src/android/build-rules/binary/src/main.rs//! Rust demo. /// Prints a greeting to standard output. fn main() { println!(Hello from Rust!); }值得注意的细节name是 Soong 模块名crate_name是 Rust crate 名二者通常保持一致。规则强制要求模块带文档注释。试着删掉main.rs顶部的//!或///注释构建时会直接报错——这是 Android 构建规则内置的文档强制机制见 Rust Binaries 演讲备注。srcs指定 crate 的源码文件列表。构建、推送与运行在 AOSP 环境中依次执行对应仓库 src/android/build_all.sh 中的hello_rust段m hello_rust adb push $ANDROID_PRODUCT_OUT/system/bin/hello_rust /data/local/tmp adb shell /data/local/tmp/hello_rust输出Hello from Rust!m是 Soong 的构建入口产物会输出到$ANDROID_PRODUCT_OUT/system/bin/下随后通过adb push推送到模拟器如 Cuttlefish的/data/local/tmp并执行。整个流程与构建一个 C 或 Java 模块并无二致。实战二用 rust_library 组织跨模块依赖单文件二进制的意义有限。rust_library用于创建可被其他模块复用的 Rust 库。下面这个例子同时声明了两个依赖libgreetings本仓库内自定义的库libtextwrap一个已 vendor 进 AOSP 的第三方 crate位于external/rust/android-crates-io/crates/目录下。对应hello_rust/Android.bp见 src/android/build-rules/library/Android.bprust_binary { name: hello_rust_with_dep, crate_name: hello_rust_with_dep, srcs: [src/main.rs], rustlibs: [ libgreetings, libtextwrap, ], prefer_rlib: true, // Need this to avoid dynamic link error. } rust_library { name: libgreetings, crate_name: greetings, srcs: [src/lib.rs], }二进制入口hello_rust/src/main.rs见 src/android/build-rules/library/src/main.rs//! Rust demo. use greetings::greeting; use textwrap::fill; /// Prints a greeting to standard output. fn main() { println!({}, fill(greeting(Bob), 24)); }库源码hello_rust/src/lib.rs见 src/android/build-rules/library/src/lib.rs//! Greeting library. /// Greet name. pub fn greeting(name: str) - String { format!(Hello {name}, it is very nice to meet you!) }构建并运行对应 src/android/build_all.sh 的hello_rust_with_dep段m hello_rust_with_dep adb push $ANDROID_PRODUCT_OUT/system/bin/hello_rust_with_dep /data/local/tmp adb shell /data/local/tmp/hello_rust_with_dep输出Hello Bob, it is very nice to meet you!此处有三点关键知识crate 名与模块名的映射名为greetings的 Rust crate 由名为libgreetings的 Soong 规则构建。Rust 代码中使用的是 crate 名use greetings::greeting;而rustlibs中声明的是 Soong 模块名——这是 Soong 依赖图的寻址方式与 Rust 的use语义各自独立。prefer_rlib: true的用途注释写明是为了避免动态链接错误Need this to avoid dynamic link error.。强制优先使用 rlib静态 Rust 库而不是 dylib在 Android 这种共享库环境复杂的系统上能规避运行时找不到符号的问题。同样的写法也出现在 AIDL 服务示例 src/android/aidl/birthday_service/Android.bp 中。第三方 crate 的树内依赖libtextwrap并非从 crates.io 在线拉取而是来自 AOSP 中已 vendor 的android-crates-io目录体现了“crate 必须在树内”的合规与性能要求。其余模块类型FFI、proc-macro、测试、模糊测试与代码生成rust_testRust 测试在 Soong 中的声明方式仓库 src/android/testing/Android.bp 展示了rust_test的多种用法rust_library { name: libleftpad, crate_name: leftpad, srcs: [src/lib.rs], } rust_test { name: libleftpad_test, crate_name: leftpad_test, srcs: [src/lib.rs], host_supported: true, test_suites: [general-tests], } rust_test { name: libgoogletest_example, crate_name: googletest_example, srcs: [googletest.rs], rustlibs: [libgoogletest_rust], host_supported: true, }可以看到测试与库共用同一份src/lib.rs通过test_suites: [general-tests]接入 Android 的通用测试框架可用atest运行host_supported: true表示该模块同时支持在主机host上构建从而可以在 PC 上直接跑测试。仓库 src/android/build_all.sh 中对应的运行命令是atest --host libleftpad_test。此外同一目录下的 src/android/testing/BUILD.bazel 还提供了等价的 Bazel 版本rust_library/rust_test印证了 Soong 与 Bazel 规则的相似性。rust_bindgen为 C 库生成 Rust 绑定FFI 场景由rust_bindgen支持它调用 bindgen 工具解析 C 头文件生成 Rust 绑定并打包为库。仓库 src/android/interoperability/with-c/bindgen.md 一节详细讲解了rust_bindgen在Android.bp中的完整用法包括header_libs、strip_include_prefix等属性是rust_ffi/rust_bindgen的配套实战材料。libbirthday_bindgen_test在 src/android/build_all.sh 中对应atest libbirthday_bindgen_test。rust_ffiRust 产出 C 库供 cc 模块使用rust_ffi是 Rust 与 C/C 互操作的另一半它生成带 C ABI 的库同时提供 static 与 shared 变体供cc_*模块链接。这解决了“Rust 调用 C”之外“C 调用 Rust”的问题配合上面的rust_bindgen构成了 Android 上 Rust/C 双向互操作的完整闭环。rust_proc_macro、rust_fuzz、rust_protobufrust_proc_macro用于编写过程宏proc-macro库机制上类似旧时代的编译器插件可对代码进行编译期变换。rust_fuzz生成基于libfuzzer的模糊测试二进制可直接接入 Android 的 fuzzing 基础设施用于挖掘内存安全漏洞。rust_protobuf输入一个.proto文件生成对应的 Rust 接口库。仓库 src/android/interoperability/java.md 中通过 AIDL 与 JNI 展示了跨语言绑定思路protobuf 生成规则遵循同样的“生成源码 打包成库”模式。综合实战日志、AIDL 服务与测试如何复用这些规则为证明上述规则在实际项目中的组合方式仓库src/android/下提供了数个可运行的完整示例。日志示例src/android/logging/Android.bp 展示了一个带依赖的rust_binaryrust_binary { name: hello_rust_logs, crate_name: hello_rust_logs, srcs: [src/main.rs], rustlibs: [ liblog_rust, liblogger, ], host_supported: true, }对应 src/android/logging/src/main.rs 中的 Rust 代码通过logfacade 与loggercrate 初始化 Android logcat 输出with_tag_on_device(rust)证明rustlibs可以把 Android 系统日志库无缝引入 Rust 生态。AIDL 服务示例src/android/aidl/birthday_service/Android.bp 则展示了库与两个二进制之间的依赖组织rust_library { name: libbirthdayservice, crate_name: birthdayservice, srcs: [src/lib.rs], rustlibs: [com.example.birthdayservice-rust], } rust_binary { name: birthday_server, crate_name: birthday_server, srcs: [src/server.rs], rustlibs: [com.example.birthdayservice-rust, libbirthdayservice], prefer_rlib: true, // To avoid dynamic link error. } rust_binary { name: birthday_client, crate_name: birthday_client, srcs: [src/client.rs], rustlibs: [com.example.birthdayservice-rust], prefer_rlib: true, // To avoid dynamic link error. }其服务端 src/android/aidl/birthday_service/src/server.rs 通过 bindgen 生成的 AIDL 绑定com.example.birthdayservice-rust注册 Binder 服务并进入线程池。运行方式见 src/android/build_all.sh构建后用service call birthdayservice 1 s16 Bob i32 24之类的adb shell命令验证。这些示例共同说明无论业务多么复杂最终都要落到rust_binary/rust_library这两个基础类型及其rustlibs依赖声明上。环境前提与运行条件本文所有命令均要求在 AOSP 环境下执行使用 Cuttlefish Android 虚拟设备参考 Android 开发者文档配置 AOSP 构建环境见 Setupsource build/envsetup.sh lunch aosp_cf_x86_64_phone-trunk_staging-userdebug acloud create为了让 AOSP checkout 识别课程中的新构建目标可以将课程仓库克隆进 AOSP或使用 bind mount见 src/android/build_all.sh 注释cd $ANDROID_BUILD_TOP mkdir comprehensive-rust sudo mount -o bind ../path/to/comprehensive-rust/src comprehensive-rust之后即可m hello_rust手动验证目标可见性再通过adb shell rm -rf /data/local/tmp/*清理后依次运行各示例。小结Soong 的 8 类 Rust 模块类型为 Android 系统软件开发提供了与 C/Java 一致的构建体验rust_binary与rust_library是日常开发的基础rust_ffi/rust_bindgen打通 C/C 互操作rust_test/rust_fuzz覆盖质量保障rust_proc_macro/rust_protobuf满足元编程与序列化代码生成需求。理解rustlibs、crate_name与prefer_rlib这几个关键属性的语义再配合madb的部署流水线你就能像编写 C 一样自然地在 Android 中构建、测试和发布 Rust 系统组件。【免费下载链接】comprehensive-rustThis is the Rust course used by the Android team at Google. It provides you the material to quickly teach Rust.项目地址: https://gitcode.com/GitHub_Trending/co/comprehensive-rust创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价