文章目录
- Cargo
- macOS配置rust环境
- vscode配置
- 目录结构
- Cargo.toml
- cargo命令
- hello world
- 跟web交互
- WebAssembly
- 跟Android交互
- 配置Android环境
- JNI例子
- NDK例子
Rust 是一种现代的、系统级的编程语言,它强调并发安全、内存安全和高性能。Rust 的设计目标是提供一种有着良好抽象能力,同时又能够保证代码运行效率和安全性的语言。它将内存安全、并发安全和数据竞争检测等特性作为语言的一部分,通过所有权系统、借用检查器和生命周期等机制来防止常见的编程错误。
下面是一些与 Rust 相关的工具和库的介绍:
-
Cargo:
Cargo 是 Rust 的包管理工具和构建系统。它能够自动管理 Rust 项目的依赖关系,并提供命令行工具来构建、测试和运行项目。Cargo 简化了 Rust 项目的创建和管理过程,使得开发者可以更专注于编写代码而不用过多关注构建细节。 -
Clippy:
Clippy 是 Rust 的静态代码分析工具,它能够检测出一些潜在的代码问题和不良习惯,并给出相应的建议。Clippy 可以帮助开发者编写更规范、更高质量的 Rust 代码。 -
Rust 文档(Rust Docs):
Rust Docs 是 Rust 官方提供的文档工具,用于生成和浏览 Rust 标准库和第三方库的文档。它为 Rust 开发者提供了一个方便的方式来查阅和学习 Rust 相关的文档。 -
Rust 标准库(Rust Standard Library):
Rust 标准库是 Rust 语言的核心库,它提供了许多常用的数据结构、算法和系统调用等功能。开发者可以直接使用标准库中的类型和函数,以快速构建高效、安全的 Rust 程序。 -
Rust 编译器(rustc):
Rust 编译器是将 Rust 代码编译为可执行文件或库的工具。它负责解析、类型检查、代码生成等编译过程,并生成适应目标平台的机器码。Rust 编译器是 Rust 语言的核心组件之一,它实现了 Rust 语言规范,并负责将 Rust 代码转化为可执行的程序。
这些工具和库都是 Rust 生态系统中重要的组成部分,它们与 Rust 的设计理念和目标相辅相成,使得开发者能够更加高效地编写、测试和维护 Rust 项目。无论是初学者还是有经验的开发者,对于这些工具的了解和使用都能够提升开发效率和代码质量。
Cargo
Cargo 是 Rust 的官方构建工具和包管理器。它用于帮助开发者构建、测试和管理 Rust 项目,简化了项目的依赖管理、构建配置和发布流程。下面详细介绍一下 Cargo 的主要功能和用法:
-
创建项目: 使用 Cargo 可以快速创建一个新的 Rust 项目。通过运行
cargo new <project_name>
命令,在当前目录下生成一个新的项目文件夹,并自动生成了一个简单的目录结构和必要的文件,包括Cargo.toml
、src/main.rs
等。 -
依赖管理: Cargo 管理 Rust 项目的依赖关系。在项目的
Cargo.toml
文件中,可以指定项目所需要的外部依赖库及其版本。当构建项目时,Cargo 会自动下载并编译这些依赖库,并将其集成到项目中。可以使用cargo build
命令来构建项目并处理依赖关系。 -
构建项目: Cargo 提供了简洁的命令行接口,可以用于构建 Rust 项目。运行
cargo build
命令将会编译项目的源代码,并生成可执行文件或库文件。Cargo 会根据项目的依赖关系自动解析和编译相关的代码。 -
运行项目: 使用
cargo run
命令可以方便地运行 Rust 项目。Cargo 会自动编译项目并执行生成的可执行文件。如果项目是一个库,可以使用cargo test
命令来运行项目中的测试用例。 -
测试项目: Cargo 提供了内置的测试框架和命令,用于编写和运行测试用例。在项目中的
src
目录下创建一个名为tests
的子目录,并在其中编写测试用例。然后使用cargo test
命令运行测试,并查看测试结果。 -
发布项目: 使用 Cargo 可以方便地发布 Rust 项目。通过运行
cargo build --release
命令,Cargo 会进行优化编译,生成一个发布版本的可执行文件。然后可以将生成的可执行文件部署到生产环境中。 -
文档生成: Cargo 提供了文档生成工具,可以生成项目的文档。在项目中的注释中添加文档注解,并使用
cargo doc
命令生成文档。生成的文档会包含项目的结构、函数、模块等信息,并可以通过浏览器进行查看。 -
更新依赖: 当项目依赖的库有新的版本发布时,可以使用 Cargo 更新依赖关系。运行
cargo update
命令,Cargo 会检查项目的依赖关系,并下载最新的版本。
除了上述功能,Cargo 还提供了其他一些辅助功能,例如初始化 Git 仓库、自动下载编译工具链(Rustup)、发布到 Cargo 社区等。这些功能使得 Cargo 成为 Rust 开发中必不可少的工具,极大地简化了项目的管理和构建过程,提高了开发效率。
macOS配置rust环境
在 macOS 上配置 Rust 环境,可以按照以下步骤进行:
-
安装 Homebrew(如果未安装):
打开终端,并执行以下命令来安装 Homebrew:/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
-
安装 Rust 编程语言:
在终端中执行以下命令来安装 Rust:curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
这将下载并运行 Rust 安装脚本。
-
配置环境变量:
安装完成后,脚本会提示你将 Rust 相关的可执行文件路径添加到环境变量中。请按照提示选择「2」或输入「2」,然后按 Enter 键。 -
初始化 Rust 环境:
执行以下命令初始化 Rust 环境:source $HOME/.cargo/env
-
验证安装:
在终端中执行以下命令验证 Rust 是否成功安装:rustc --version cargo --version
-
安装 wasm-pack:
这将下载并执行 wasm-pack 安装脚本。根据提示,可能需要输入管理员密码来完成安装。curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh wasm-pack --version
如果以上步骤没有出现任何错误,那么你的 macOS 系统上已成功配置了 Rust 环境。你可以开始使用 Rust 编程语言进行开发了。需要注意的是,Rust 包管理器 Cargo 也已经安装好了,它可以帮助你管理 Rust 项目的依赖和构建过程。
希望上述步骤能够帮助到你顺利配置 Rust 环境。如果在安装过程中遇到任何问题,你可以参考 Rust 官方文档 或 Rust 社区中的相关资源来获取更多帮助。
vscode配置
当在 VS Code 中配置 Rust 开发环境时,以下是几个常用的插件推荐:
-
rust-analyzer:这是官方提供的 Rust 插件,是一个功能强大的 Rust 语言服务器,它提供了智能代码补全、重构建议、错误检查等高级功能。
-
Crates by serayuzgur:这个插件提供了对 Cargo.toml 和 Cargo.lock 文件的支持,可以方便地查看和管理项目的依赖关系。
-
CodeLLDB by Vadim Chugunov:如果你需要在 VS Code 中进行 Rust 代码的调试,这个插件可以与 LLDB 调试器集成,提供了强大的调试功能。
-
Better TOML by bungcip:这个插件提供了对 TOML 文件的语法高亮和格式化支持,对于编辑 Cargo.toml 文件来说非常实用。
-
Rusty Code by matklad:Rusty Code 插件提供了代码格式化、自动导入缺失的模块、错误检查等功能,帮助减少开发中的一些常见错误。
以上这些插件可以为你提供更好的 Rust 开发体验,使得在 VS Code 中编写、调试和管理 Rust 项目更加便捷和高效。可以通过在 VS Code 中搜索插件名称并安装来开始配置 Rust 开发环境。同时,也可以根据自己的需求和喜好,探索其他的 Rust 插件。
目录结构
Rust 项目通常遵循一种常见的目录结构,该结构有助于组织代码、资源文件和构建工具。以下是一个常见的 Rust 项目目录结构示例:
myproject/├── src/│ └── main.rs├── Cargo.toml└── Cargo.lock
让我们逐个解释每个目录和文件的作用:
-
src/
:这是存放 Rust 源代码的目录。你可以在此目录下创建多个.rs
文件来组织你的代码。通常,你会在src/
目录下创建一个main.rs
文件,其中包含项目的入口点。 -
main.rs
:这是包含项目入口点(例如main
函数)的 Rust 源代码文件。它是 Rust 程序的起点,负责启动应用程序的执行流程。 -
Cargo.toml
:这是 Rust 项目的配置文件,使用 Toml 格式来描述项目的依赖项、构建选项和其他元数据。你可以在Cargo.toml
中指定项目名称、版本号、作者信息等。 -
Cargo.lock
:这是由 Cargo 自动生成的锁定文件。它记录了实际使用的依赖项及其确切版本,以确保在后续构建中使用相同的依赖项版本。
除了上述基本结构之外,Rust 项目通常还包括其他目录和文件:
-
tests/
:如果你的项目包含测试代码,通常会在此目录下创建测试文件。测试代码用于验证项目中各个部分的正确性。 -
examples/
:如果你想提供一些示例用法或演示代码,可以将其放置在此目录下。 -
target/
:这是 Cargo 自动生成的目录,在构建过程中存储目标文件和编译生成的二进制可执行文件。 -
build.rs
:这是一个可选的构建脚本文件,使用 Rust 代码编写。它允许你在构建过程中自定义一些操作,例如生成代码、配置构建选项等。 -
其他自定义目录:根据项目的需要,你可能还会创建其他自定义的目录,用于存放静态资源文件、模板文件、配置文件等。
请注意,Rust 的目录结构没有强制要求,你可以根据项目的需求进行调整和扩展。上述目录结构只是一个常见的约定,大多数 Rust 项目都遵循类似的结构来提供一致性和易于理解的代码组织方式。
Cargo.toml
Cargo.toml
是 Rust 项目的配置文件,用于指定项目的元数据、依赖项和构建选项。它使用 Toml 格式(Tom’s Obvious, Minimal Language)编写,是一种易于理解和编辑的简单配置语言。要详细了解Cargo请阅读manifest。
下面是一个典型的 Cargo.toml
示例:
[package]
name = "myproject"
version = "0.1.0"
edition = "2021"[dependencies]
crate1 = "1.0"
crate2 = { version = "2.0", features = ["feature1", "feature2"] }[build-dependencies]
build_crate = "1.0"
让我们逐个解释每个部分的含义:
-
[package]
: 这个部分用于指定项目的元数据信息。name
:指定项目的名称。version
:指定项目的版本号。edition
:指定 Rust 的版本。支持的选项有"2015"
、"2018"
和"2021"
。
-
[dependencies]
: 这个部分用于指定项目的依赖项。你可以列出项目所依赖的外部库或 crate,并指定它们的版本信息。crate1 = "1.0"
:这表示项目依赖名为crate1
的 crate,并指定其版本为1.0
。crate2 = { version = "2.0", features = ["feature1", "feature2"] }
:这表示项目依赖名为crate2
的 crate,并指定其版本为2.0
,同时启用其中的一些特性。
-
[build-dependencies]
: 这个部分用于指定项目构建过程中所需要的依赖项。这些依赖项只在构建过程中使用,而不会包含在最终的二进制可执行文件中。
除了上述常见的部分之外,Cargo.toml
文件还支持其他配置选项,如:
workspace
:用于同时管理多个相关的 Rust 项目。features
:用于定义和启用 crate 的不同功能特性。target
:用于指定特定的目标平台和相关设置。patch
:用于修复或替换依赖项的特定版本。
你可以根据项目的需求自定义 Cargo.toml
文件,添加适当的依赖项、配置选项和元数据信息。Rust 的构建工具 Cargo 将根据 Cargo.toml
中的配置来下载和管理依赖项,并执行相应的构建操作。
希望这个介绍对你有所帮助!如果还有其他问题,请随时提问。
cargo命令
Cargo 是 Rust 的官方构建工具和包管理器,提供了许多命令用于构建、测试、管理和发布 Rust 项目。以下是 Cargo 的常用命令列表:
-
cargo new
:创建一个新的 Rust 项目。 -
cargo build
:构建项目,编译源代码并处理依赖关系。 -
cargo run
:运行项目,编译并执行生成的可执行文件。 -
cargo test
:运行测试用例。 -
cargo bench
:运行基准测试。 -
cargo doc
:生成项目文档。 -
cargo clean
:清理项目构建产生的临时文件和目录。 -
cargo update
:更新项目的依赖库。 -
cargo init
:初始化当前目录为一个 Rust 项目。 -
cargo check
:检查代码是否可以成功编译,但不生成可执行文件。 -
cargo fix
:自动修复一些编译警告和错误。 -
cargo publish
:发布项目到 crates.io,Rust 社区的包管理平台。 -
cargo install
:安装一个二进制包程序到系统路径。 -
cargo uninstall
:卸载一个已安装的二进制包程序。 -
cargo package
:生成一个用于发布的压缩包。 -
cargo metadata
:显示项目的元数据信息,依赖关系等。 -
cargo fmt
:格式化源代码。 -
cargo clippy
:运行 Clippy(Rust 的 lint 工具)对代码进行静态分析。 -
cargo doc --open
:生成文档并在浏览器中打开。 -
cargo build --release
:生成发布版本的可执行文件。 -
cargo build --target <target>
:指定目标平台进行构建。 -
cargo build --features <features>
:启用指定的特性进行构建。 -
cargo build --no-default-features
:禁用默认特性进行构建。 -
cargo build --all
:构建项目及其所有依赖。 -
cargo build --workspace
:在工作区中构建所有子项目。 -
cargo build --lib
:只构建项目中的库文件。 -
cargo build --bin <name>
:只构建指定名称的可执行文件。 -
cargo build --example <name>
:只构建指定名称的示例程序。 -
cargo build --tests
:只构建项目中的测试目标。 -
cargo build --benches
:只构建项目中的基准测试目标。 -
cargo build --target-dir <dir>
:指定构建输出的目录。 -
cargo build --all-features
:启用所有特性进行构建。 -
cargo build --no-default-runtime
:禁用默认运行时(仅适用于编写运行时的 Crate)。 -
cargo test -- --test-threads=<num>
:设置并发运行测试的线程数。 -
cargo test -- <pattern>
:只运行与指定模式匹配的测试。 -
cargo test -- --ignored
:运行被标记为#[ignore]
的测试。 -
cargo test --release
:以发布模式运行所有测试。 -
cargo doc --no-deps
:生成项目文档,但不包含依赖库的文档。 -
cargo run -- <args>
:在编译并运行项目时传递参数。 -
cargo check --all-targets
:检查项目及其所有目标的代码是否可以成功编译。 -
cargo fix --edition
:自动升级代码到指定的 Rust 版本。 -
cargo fix --allow-dirty
:允许在 Git 工作目录中运行cargo fix
。 -
cargo publish --dry-run
:发布前进行 dry-run,检查是否有错误。 -
cargo publish --allow-dirty
:允许在 Git 工作目录中运行cargo publish
。 -
cargo install <crate>
:安装指定的 Crate。 -
cargo install-update <crate>
:更新指定的 Crate。 -
cargo uninstall <crate>
:卸载指定的 Crate。 -
cargo search <query>
:在 crates.io 中搜索包。 -
cargo clean --package <spec>
:清理指定的 Package。 -
cargo metadata --format-version <version>
:指定元数据格式的版本。
这些是常用的 Cargo 命令,可以帮助你管理 Rust 项目的构建、测试、文档生成、依赖管理和发布等任务。你可以通过在命令行中输入 cargo --help
来查看更多命令以及它们的详细使用说明。
hello world
要开始你的第一个 Rust “Hello, World!” 项目,按照以下步骤进行:
-
安装 Rust 编程语言:首先,确保您已在计算机上安装了 Rust。可以访问 Rust 官方网站,按照指示下载并安装 Rust。
-
创建新项目:打开终端或命令提示符,导航到要创建项目的目录,并运行以下命令来创建一个新的 Rust 项目:
cargo new hello_world
这将在当前目录下创建一个名为 “hello_world” 的新目录,并自动生成一些初始代码。
-
进入项目目录:运行以下命令以进入新创建的项目目录:
cd hello_world
-
编辑代码:使用你喜欢的文本编辑器打开
src/main.rs
文件,并将以下代码复制粘贴到文件中:fn main() {println!("Hello, World!"); }
-
构建和运行项目:返回终端或命令提示符,运行以下命令来构建和运行你的项目:
cargo run
Rust 的构建系统 Cargo 将编译项目并运行生成的可执行文件。你应该会在终端上看到输出 “Hello, World!”。
恭喜!你已经成功创建并运行了你的第一个 Rust “Hello, World!” 项目。从这个简单的示例开始,你可以继续学习和探索 Rust 编程语言的更多方面。
跟web交互
Rust 可以与 Web 进行交互,使你能够构建 Web 应用程序、API 和后端服务。下面是一些可以帮助你在 Rust 中进行 Web 交互的常见方法:
-
Web 框架:使用 Rust 的 Web 框架可以简化 Web 开发过程,并提供路由、请求处理、中间件等功能。一些流行的 Rust Web 框架包括 Rocket、Actix-web 和 Warp。
-
HTTP 客户端和服务器:Rust 提供了多个库用于构建 HTTP 客户端和服务器。例如,reqwest 是一个常用的 HTTP 客户端库,hyper 是一个强大的 HTTP 服务器库。
-
数据库访问:与 Web 相关的应用程序通常需要与数据库进行交互。Rust 提供了各种数据库连接库和 ORM(对象关系映射)工具,例如 Diesel、sqlx 和 rusqlite。
-
模板引擎:用于生成动态 HTML 页面的模板引擎在 Web 开发中非常有用。Rust 中一些流行的模板引擎包括 Tera 和 Handlebars。
-
WebAssembly(Wasm):Rust 具备编写 WebAssembly 模块的能力,这使得你可以在 Web 浏览器中运行原生速度的 Rust 代码。你可以使用 wasm-bindgen 和 wasm-pack 工具来构建和集成 Rust 和 JavaScript 之间的接口。
-
WebSocket:Rust 提供了用于 WebSocket 通信的库,如 tokio-tungstenite 和 actix-web 的 WebSocket 功能。
以上只是一些在 Rust 中进行 Web 交互的方法示例,你可以根据具体需求选择合适的库和工具。Rust 社区拥有丰富的资源和文档,可以帮助你深入了解和学习 Rust 的 Web 开发。
WebAssembly
以下是一个使用 Rust 和 WebAssembly(Wasm)进行交互的示例:
首先,确保你已经安装了 Rust 和 wasm-pack 工具。
-
创建新的 Rust 项目:
打开终端或命令提示符,导航到要创建项目的目录,并运行以下命令来创建一个新的 Rust 项目:cargo new wasm_example cd wasm_example
-
添加依赖:
在项目的根目录中,打开Cargo.toml
文件,并添加以下代码来添加 wasm-bindgen 和 js-sys 的依赖:[lib] crate-type = ["cdylib"][dependencies] wasm-bindgen = "0.2" js-sys = "0.3"
-
编写 Rust 代码:
打开src/lib.rs
文件,并使用以下代码替换其中的内容:use wasm_bindgen::prelude::*;#[wasm_bindgen] extern "C" {#[wasm_bindgen(js_namespace = console)]fn log(s: &str); }#[wasm_bindgen] pub fn greet(name: &str) {let message = format!("FromRust, {}!", name);log(&message); }
上述代码定义了一个
greet
函数,它接受一个字符串参数,并在控制台输出问候消息。 -
生成 Wasm 模块:
在终端中运行以下命令来生成 Wasm 模块:wasm-pack build --target web
这将使用 wasm-pack 工具将 Rust 代码编译为 WebAssembly 模块,并生成与 JavaScript 交互的必要代码。
-
创建 HTML 文件:
在项目的根目录中,创建一个名为index.html
的文件,并使用以下代码填充它:<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>WebAssembly Example</title><script type="module">import init, { greet } from './pkg/wasm_example.js';async function run() {await init();greet("Alice");}run();</script> </head> <body> </body> </html>
上述代码导入了生成的
wasm_example.js
文件,并在页面加载完成后调用greet
函数。 -
启动本地服务器:
在终端中运行以下命令来启动一个简单的本地服务器:python -m http.server
-
运行示例:
打开浏览器并访问http://localhost:8000
,然后打开浏览器的控制台。你应该会看到控制台输出了 “Hello, Alice!”。
通过上述步骤,你可以在 Rust 中创建一个简单的 WebAssembly 模块,并与 JavaScript 进行交互。你可以根据需要扩展这个示例,并使用更多的 Rust 函数与 JavaScript 进行交互。
跟Android交互
当你想要在 Android 平台上使用 Rust 与 Java 进行交互时,下面是一些具体的步骤和工具可以帮助你实现这一目标:
-
使用 JNI(Java Native Interface):JNI 提供了一种方式,使得 Java 和本地代码能够进行交互。你可以使用 Rust 编写本地代码,并通过 JNI 接口与 Android 的 Java 代码进行通信。为了在 Rust 中与 JNI 交互,你可以使用
jni
或rust-jni
等库来编写相应的绑定代码。需要完成的步骤:
- 编写 Rust 的绑定代码,将 Rust 函数暴露给 JNI。
- 生成动态链接库(
.so
文件)。 - 在 Android 项目中使用 JNI 接口调用 Rust 函数。
-
使用 NDK(Native Development Kit):NDK 允许你使用 C、C++ 或其他本地语言来开发 Android 应用程序。你可以使用 Rust 作为 C 或 C++ 的替代语言,并在 NDK 中构建包含 Rust 代码的本地库。然后,你可以使用 Java 代码通过 JNI 调用这些本地库。
需要完成的步骤:
- 创建 Android NDK 项目,并配置好 Rust 的构建环境。
- 编写 Rust 代码并构建共享库(
.so
文件)。 - 使用 JNI 接口在 Java 代码中调用本地库中的函数。
-
使用 FFI(Foreign Function Interface):FFI 允许不同语言之间进行函数调用和数据传递。你可以使用 Rust 的 FFI 功能,将 Rust 函数暴露给其他语言,比如 Java。通过这种方式,你可以在 Android 的 Java 代码中直接调用 Rust 函数。
需要完成的步骤:
- 使用 Rust 的
#[no_mangle]
和extern
关键字将函数标记为可供外部调用。 - 根据 FFI 规范编写 Java 代码来调用 Rust 函数。
- 在 Android 项目中将 Rust 代码和 Java 代码一起编译和构建。
- 使用 Rust 的
-
使用
rust-android-gradle
插件:rust-android-gradle
是一个方便的工具,可用于将 Rust 代码集成到 Android 项目中。它可以自动处理 Rust 代码的构建和链接,并与 Gradle 构建系统集成。需要完成的步骤:
- 在 Android 项目的 Gradle 文件中添加
rust-android-gradle
插件的依赖。 - 创建 Rust 模块并设置构建配置。
- 在 Android 项目中使用预生成的 Rust 库。
- 在 Android 项目的 Gradle 文件中添加
请注意,在实施任何方法之前,你需要确保已经按照相应工具和库的文档进行了正确的配置和设置。每种方法都有其优势和适用场景,因此根据需求选择最适合你的方法。
希望这些详细的步骤能够帮助你更好地理解 Rust 与 Android 的交互,并实现你的项目需求。
配置Android环境
要正确安装和配置 Android NDK,请按照以下步骤进行操作:
-
下载 Android NDK:访问 Android NDK 的官方网站下载适合你操作系统的最新版本。
-
解压缩文件:将下载的 NDK 压缩文件解压到你选择的位置。例如,你可以将其解压到
~/android-ndk
目录下。 -
配置环境变量:打开终端并编辑你的 shell 配置文件(例如
~/.bashrc
或~/.zshrc
)。在文件末尾添加以下行(假设你将 NDK 解压缩到了~/android-ndk
目录):export ANDROID_NDK_HOME=~/android-ndk export PATH=$PATH:$ANDROID_NDK_HOME
保存文件后执行以下命令使配置立即生效:
source ~/.bashrc
或者你也可以重新启动终端。
-
测试安装:在终端中运行以下命令验证是否正确安装和配置了 Android NDK:
ndk-build --version
如果成功安装并配置,将显示 NDK 版本信息。
-
安装交叉编译目标:运行以下命令来安装 aarch64-linux-android 目标:
rustup target add aarch64-linux-android rustup target add arm-linux-androideabi rustup target add armv7-linux-androideabi rustup target add i686-linux-android rustup target add thumbv7neon-linux-androideabi rustup target add x86_64-linux-android
-
配置链接器和编译参数:创建一个名为
$HOME/.cargo
的文件夹,并在其中创建一个名为config
的文件。在config
文件中添加以下内容:[target.arm-linux-androideabi] ar = "llvm-ar" linker = "armv7a-linux-androideabi29-clang"[target.armv7-linux-androideabi] ar = "llvm-ar" linker = "armv7a-linux-androideabi29-clang"[target.thumbv7neon-linux-androideabi] ar = "llvm-ar" linker = "armv7a-linux-androideabi29-clang"[target.aarch64-linux-android] ar = "llvm-ar" linker = "aarch64-linux-android29-clang"[target.i686-linux-android] ar = "llvm-ar" linker = "i686-linux-android29-clang"[target.x86_64-linux-android] ar = "llvm-ar" linker = "x86_64-linux-android29-clang"
-
测试编译:现在,你可以尝试使用 Cargo 构建你的项目,并将目标设置为 Android 平台,例如:
cargo build --target aarch64-linux-android
通过按照以上步骤配置 Rust 的交叉编译环境,你应该能够开始在 Android 平台上使用 Rust 进行交叉编译了。
JNI例子
当使用 JNI 实现 Rust 与 Android 的交互时,可以使用以下示例来说明具体步骤。假设你希望在 Android 应用程序中调用一个计算两个整数和的 Rust 函数。
-
创建一个名为
rust_lib
的 Rust 项目cargo new rust_lib --lib
,并添加以下内容到lib.rs
文件中:#[no_mangle] pub extern "C" fn rust_greet(name: *const c_char) -> *mut c_char {let c_str = unsafe {assert!(!name.is_null());CStr::from_ptr(name)};let name = c_str.to_str().unwrap();let greeting = format!("FromRust, {}!", name);CString::new(greeting).unwrap().into_raw() }
-
在
Cargo.toml
文件中添加以下内容:[lib] crate-type = ["cdylib"]
-
使用以下命令在 Rust 中构建共享库文件:
cargo build --target aarch64-linux-android
上述命令将在
target/aarch64-linux-android/debug/librust_lib.so
中生成共享库文件。 -
在 Android 项目中的
app
模块下的src/main
目录中创建一个名为jni
的文件夹,并在其中创建一个native-lib.cpp
文件。 -
在
native-lib.cpp
文件中添加以下内容:#include <jni.h> #include <string> #include <dlfcn.h>extern "C" JNIEXPORT jstring JNICALL Java_com_example_androidapp_MainActivity_stringFromJNI(JNIEnv* env,jobject /* this */,jstring name) {const char* nativeString = env->GetStringUTFChars(name, nullptr);void* handle = dlopen("librust_lib.so", RTLD_LAZY);if (!handle) {return env->NewStringUTF("Failed to load Rust library");}typedef char* (*rust_greet_func)(const char*);rust_greet_func greet = (rust_greet_func)dlsym(handle, "rust_greet");if (!greet) {return env->NewStringUTF("Failed to find Rust function");}char* result = greet(nativeString);env->ReleaseStringUTFChars(name, nativeString);jstring output = env->NewStringUTF(result);free(result);dlclose(handle);return output; }
要把
librust_lib.so
复制到jniLibs对应的目录中。 -
配置cmake
app build.gradle
android {// ...defaultConfig {// ...externalNativeBuild {cmake {cppFlags '-std=c++17'}}ndk {abiFilters "arm64-v8a"}}sourceSets {main {// 配置 jniLibs 文件目录jniLibs.srcDirs = ['libs']}}externalNativeBuild {cmake {path file('src/main/cpp/CMakeLists.txt')version '3.22.1'}} }
CMakeLists.txt
cmake_minimum_required(VERSION 3.22.1) project("rust_jni") add_library(${CMAKE_PROJECT_NAME} SHARED native-lib.cpp) target_link_libraries(${CMAKE_PROJECT_NAME} android log)
-
在 Android 项目的 Java 类中,添加以下方法:
public class MainActivity extends AppCompatActivity {static {System.loadLibrary("native-lib");}public native String stringFromJNI(String name);// ... }
-
在
MainActivity.java
中的任何适当的方法中调用stringFromJNI()
方法,并向其传递一个字符串参数:String greeting = stringFromJNI("Stone " + new Date().toString()); Log.d("MainActivity", greeting);
这样,在 Android 应用程序中运行时,将调用 Rust 函数并输出日志中的问候语。
NDK例子
当使用 Rust 和 Android NDK 进行开发时,以下是一个详细的示例,展示如何在 Android 项目中使用 Rust 编写并调用函数。
-
创建 Rust 项目:
在终端中执行以下命令,创建一个名为
rust-ndk
的 Rust 项目:cargo new rust-ndk
进入项目目录:
cd rust-ndk
-
添加依赖项:
打开项目中的
Cargo.toml
文件,并添加ndk
、jni
和libc
作为依赖项:[lib] crate-type = ["cdylib"] path = "src/jni.rs"[dependencies] jni = "0.21.1"
-
创建 JNI 接口:
在项目的根目录下创建一个名为
jni.rs
的文件,并添加以下代码:use jni::JNIEnv; use jni::objects::{JClass, JString}; use jni::sys::jstring;#[no_mangle] pub unsafe extern "C" fn Java_com_example_rustndk_MainActivity_stringFromRust<'local>(mut env: JNIEnv<'local>,_: JClass<'local>,input: JString<'local>)-> jstring {let input: String = env.get_string(&input).expect("Couldn't get java string!").into();let output = env.new_string(format!("FromRust, {}!", input)).expect("Couldn't create java string!");output.into_raw() }
这个例子中的
Java_com_example_rustndk_MainActivity_stringFromRust
函数是一个 JNI 方法,在字符串前面拼接一个FromRust
字符串。 -
构建 Rust 项目:
在终端中执行以下命令构建 Rust 项目:
cargo build --target aarch64-linux-android --release
-
创建 Android 项目:
使用 Android Studio 创建一个新的 Android 项目,并导航到
app/src/main
目录。 -
添加 Rust 动态链接库:
将生成的
.so
文件复制到app/src/main/jniLibs
目录下(如果没有该目录则自行创建)。例如,将../rust-ndk/target/release/librust_ndk.so
文件复制到app/src/main/jniLibs/arm64-v8a/
目录下。 -
创建 Java 类和 JNI 接口:
在
app/src/main/java/com/example/rustndk
目录下创建一个名为MainActivity.java
的类,并添加以下代码:package com.example.rustndk;public class MainActivity extends AppCompatActivity {static {System.loadLibrary("rust_ndk");}private ActivityMainBinding binding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = ActivityMainBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());// Example of a call to a native methodTextView tv = binding.sampleText;tv.setText(stringFromRust("Stone " + new Date().toString()));}public native String stringFromRust(String str); }
这个类包含了一个静态代码块,用于加载名为
rust_ndk
的动态链接库。还有一个名为stringFromRust
的方法,用于调用 Rust 函数。
这样,在 Android 应用程序中运行时,将调用 Rust 函数并输出日志中的问候语。