ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

comprehensive-rust 课程详解:在 Chromium 中使用 gn 与 ninja 构建 Rust 代码(Build Rules)

comprehensive-rust 课程详解:在 Chromium 中使用 gn 与 ninja 构建 Rust 代码(Build Rules) comprehensive-rust 课程详解在 Chromium 中使用 gn 与 ninja 构建 Rust 代码Build Rules【免费下载链接】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导读Chromium 是世界上代码量最大的开源项目之一其构建体系基于gn与ninja这套体系以静态规则、最大并行度著称。本文基于 comprehensive-rust 课程中的 Chromium 专题文档 src/chromium/build-rules.md系统讲解如何在 Chromium 中通过rust_static_library模板声明 Rust 静态库、理解crate_root与sources的语义差异、为 Rust 目标声明依赖关系并结合仓库中的练习文件与相关源码给出可复制、可运行的完整示例。读完本文你将掌握在 Chromium 构建体系中正确引入并构建 Rust 代码的核心方法理解为何需要自定义 gn 模板而非使用 gn 内置的 Rust 静态库支持以及allow_unsafe等关键参数的使用场景。背景Chromium 为何不用 cargo 构建 Rust在 Rust 社区中cargo是事实上的标准构建工具绝大多数 Rust 项目依赖cargo、crates.io与Cargo.toml来组织依赖与编译。Chromium 则不同其全量构建使用gn生成 ninja 文件再由ninja执行并行编译从而获得最大化的构建效率。这一背景在课程文档 src/chromium/cargo.md 中有更完整的对比说明维度C 库Rust crate构建系统多种并存一致Cargo.toml典型库规模较大较小传递依赖少多表格引自 src/chromium/adding-third-party-crates.md因此当 Rust 代码需要被编译进 Chromium 浏览器本身时就必须融入gn/ninja体系而不能直接交给cargo。Chromium 提供位于//build/rust/*.gni的一组模板如rust_static_library来桥接这两个世界并使用经过审计的 Rust 工具链与精选第三方 crate。核心概念rust_static_library模板在 Chromium 的某个现有BUILD.gn文件中可以通过如下方式声明一个 Rust 静态库目标import(//build/rust/rust_static_library.gni) rust_static_library(my_rust_lib) { crate_root lib.rs sources [ lib.rs ] }这段代码完整保留自 src/chromium/build-rules.md包含了两个关键参数crate_root传给 Rust 编译器的编译单元根文件通常为lib.rs它决定了 crate 的入口sources完整的源文件清单ninja依赖这份清单来判断何时需要触发重新编译。为什么必须同时声明 crate_root 与 sources文档特别强调两个参数都必须显式给出。crate_root告诉编译器从哪个文件开始编译整个编译单元而sources是ninja做增量构建判断哪些文件变化需要重编的依据。二者职责不同缺一不可。为什么 Rust 没有 source_set 概念文档中特别解释了这一点在 Rust 中整个 crate 就是一个编译单元不存在 C 体系里那种更细粒度的source_set。static_library是 Rust 目标的最小单位。这也是rust_static_library成为 Chromium 中 Rust 目标基本形态的原因。为什么需要 gn 模板而不是 gn 内置支持gn 本身对 Rust 静态库有内置支持详见 gn 官方文档的static_library函数说明原文档以脚注形式给出了官方链接 [0]。但 Chromium 的rust_static_library模板在其之上额外提供了以下能力CXX 互操作支持为 Rust 与 C 的 FFI 桥接提供构建期支持相关内容见 src/chromium/interoperability-with-cpp.mdChromium 使用 CXX 工具在 Rust 中通过#[cxx::bridge]模块声明整个 C/Rust 边界示例见 src/chromium/interoperability-with-cpp/example-bindings.mdRust feature 支持为 Rust 目标提供统一的 feature 声明与传递机制单元测试支持便于在构建体系中组织测试目标。课程文档指出这些能力中的一部分会在后续章节如第三方 crate 引入、C 互操作中实际用到。依赖声明deps 与第三方代码除了crate_root与sourcesrust_static_library目标同样支持deps参数用于依赖其他 Rust 目标。文档明确说明You can also adddepson other Rust targets. Later well use this to depend upon third party code.在后续章节src/chromium/adding-third-party-crates.md中课程会讲解如何将第三方 crate 放入 Chromium 源码树、为其生成gn构建规则并审计其源码安全性。届时deps就是把这些 crate 目标接入第一方代码的关键通道。实战在 Chromium 中构建并调用一个 Rust 目标课程配套练习 src/exercises/chromium/build-rules.md 给出了一个完整、可复现的实战流程它直接建立在本文所讲的构建规则之上在//ui/base/BUILD.gn中添加一个新的 Rust 目标内容如下// SAFETY: There is no other global function of this name. #[unsafe(no_mangle)] pub extern C fn hello_from_rust() { println!(Hello from Rust!) }注意no_mangle属于不安全代码文档强调#[unsafe(no_mangle)]被 Rust 编译器视为一种不安全操作它可能允许 Rust 生成两个同名函数从而使编译器无法保证调用到正确的那一个因此需要在gn目标中显式allow_unsafe true。将该 Rust 目标作为//ui/base:base的依赖添加进去。在ui/base/resource/resource_bundle.cc顶部声明该函数后续课程会讲解如何用 bindings 生成工具自动化这一步骤extern C void hello_from_rust();在ui/base/resource/resource_bundle.cc的某处调用它课程建议放在ResourceBundle::MaybeMangleLocalizedString顶部然后构建并运行 Chromium确认终端大量打印 Hello from Rust!。练习文档还给出了若干排障与深化线索查看rust_static_librarygn 模板的可选参数文档脚注指向 source.chromium.org 上build/rust/rust_static_library.gni的对应行查阅#[unsafe(no_mangle)]与extern C的官方文档说明若需要纯 Rust 可执行文件可使用rust_executablegn 模板若使用 VSCode可利用 gn 的--export-rust-project开关导出编译数据库配合 rust-analyzer 获得 Go to definition 等 IDE 能力。这个例子刻意使用了 C ABI 作为互操作的最小公分母C 与 Rust 都能原生声明并调用 C ABI 函数。后续课程章节将在此基础上讲解如何让 C 直接连接 Rust。构建与运行前提要在 Chromium 中实践上述内容需要先具备可构建、可运行的 Chromium 开发环境。课程文档 src/chromium/setup.md 给出的最低要求是gn gen out/Debug autoninja -C out/Debug chrome out/Debug/chrome # or on Mac, out/Debug/Chromium.app/Contents/MacOS/Chromium建议使用 component debug 构建这也是默认配置以获得最快的迭代速度代码需相对较新commit position 1223636 起对应 2023 年 11 月建议安装 VSCode 以便配合 rust-analyzer 使用。小结Chromium 用gn/ninja构建 Rust通过//build/rust/rust_static_library.gni模板声明 Rust 静态库目标crate_root与sources必须同时指定前者定义编译单元入口后者驱动 ninja 增量构建Rust 中一个 crate 即一个编译单元所以static_library是最小单位不存在 Rust 版的source_set模板相比 gn 内置支持额外提供 CXX 互操作、Rust feature 与单元测试支持deps用于依赖其他 Rust 目标是后续接入第三方 crate 的通道通过练习src/exercises/chromium/build-rules.md可以在//ui/base中实际构建一个导出extern C函数的 Rust 库并从 C 侧调用验证整套构建规则。延伸阅读Chromium 专题总览Rust 在 Chromium 中支持第三方库第一方胶水代码负责连接 Rust 与既有 C 代码Cargo 与 Chromium 生态对比cargo 的优势、风险与 Chromium 审计工具链C 互操作CXX 工具与#[cxx::bridge]边界声明测试Chromium 中 Rust 测试的三种组织方式原生#[test]、C 侧 gtest、Rust 侧 gtest。【免费下载链接】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),仅供参考
返回列表