README.md

ArkUI-X支持Rust sample开发

介绍

本示例通过DevEco创建一个[ArkUI-X] Native C++跨平台工程,用来实现鸿蒙、Android和iOS调用rust接口。

效果预览

  • Android平台展示效果

  • iOS平台展示效果

  • OH平台展示效果

使用说明

1、在运行本示例前,需要参照配置说明进行相关环境与工程的配置。

2、打开应用,进入 "Hello Rust" 页面。

3、点击 "10 + 20" 按钮调用rust的默认提供的add接口,主页面上显示得到的结果。

4、点击 "新增方法: 30 - 10" 按钮调用rust增加的subtract接口,主页面上显示得到的结果。

工程目录

rust_add								// rust工程
├── src
│   └── lib.rs							// rust接口文件
├── build.rs							// rust构建配置文件
└── Cargo.toml

RustDev									// Native C++跨平台工程
├── .arkui-x
│   ├── android							// Android 工程
│   ├── ios								// iOS 工程
│   └── arkui-x-config.json5
├── AppScope
├── entry
│   ├── build-profile.json5
│   ├── hvigorfile.ts
│   ├── obfuscation-rules.txt
│   ├── oh-package.json5
│   └── src
│       ├── main
│       │   ├── cpp
│       │   ├── ets
│       │   │   ├── pages
│       │   │   │   └── Index.ets		// 主界面
│       │   │   └── entryability
│       │   │       └── EntryAbility.ets
│       │   ├── module.json5
│       │   └── resources
│       ├── mock
│       ├── ohosTest
│       └── test
├── hvigor
├── build-profile.json5
├── hvigorfile.ts
├── oh-package.json5
├── screenshots
└── README.md

具体实现

  • 打开应用后进入首页Index.ets。通过引入rust工程编译出的动态库librust_add.so,来调用rust的接口。

配置说明

一、相关环境配置

1、安装Rust工具链

(1)打开终端,执行以下命令下载并安装 Rust

Mac端

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Windows端

需要进入Rust官网下载rustup-init.exe,进行安装。

(2)激活环境变量

安装完成后,需加载 Rust 工具链的路径到当前 Shell 环境:

Mac端

source "$HOME/.cargo/env"

若后续重启终端后命令失效,可将该命令添加到 Shell 配置文件(如 ~/.zshrc 或 ~/.bash_profile)中。

Windows端

无需配置环境变量。

(3)验证安装

执行以下命令检查rust和cargo版本信息,若显示版本号则安装成功:

rustc --version
cargo --version

(4)使用cargo安装脚手架工具ohrs

cargo install ohrs

(5)验证ohrs安装

ohrs doctor

若安装成功,则会有如下结果:

Windows端可能会有乱码,不影响正常使用

✔  Environment variable OHOS_NDK_HOME should be set.
✔  Rust version should be >= 1.78.0.
✔  Rustup target: aarch64-unknown-linux-ohos should be installed.
✔  Rustup target: armv7-unknown-linux-ohos should be installed.
✔  Rustup target: x86_64-unknown-linux-ohos should be installed.

(6)修改Cargo配置文件名称

进入.cargo文件夹,修改config文件的名称为config.toml,若找不到config文件可直接新建一个名称为config.toml的空文件,可通过以下命令找到.cargo文件夹位置:

where cargo

2、需要安装 Rust 的 toolchain 来帮助构建相应平台的动态库

鸿蒙平台

rustup target add aarch64-unknown-linux-ohos
rustup target add armv7-unknown-linux-ohos
rustup target add x86_64-unknown-linux-ohos

Android平台

rustup target add aarch64-linux-android
rustup target add armv7-linux-androideabi
rustup target add x86_64-linux-android

iOS平台

rustup target add aarch64-apple-ios
rustup target add x86_64-apple-ios
rustup target add aarch64-apple-ios-sim

二、鸿蒙上如何调用rust

环境

1、配置​OHOS_NDK_HOME​环境变量:

该目录指向了DevEco Studio安装目录中的openharmony sdk,您需要根据您DevEco Studio具体的安装位置调整变量值

Mac端

export OHOS_NDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony

Windows端

需要在环境变量中配置,如下图:

变量:OHOS_NDK_HOME,值:/DevEco安装目录/sdk/default/openharmony

编译

1、使用ohrs来创建一个新的rust项目,或者您可以直接使用Sample中的rust_add项目:

ohrs init rust_add

若创建成功,则会有如下输出:

Create lib.rs succeed.
Create build.rs succeed.
Create .gitignore succeed.
Create Cargo.toml succeed.

3、之后使用ohrs来构建项目:

cd rust_add
ohrs build

执行完成后会生成一个dist目录,其中含有librust_add.so文件和index.d.ts文件。

4、使用鸿蒙开发工具DevEco创建一个ArkUI-X Native C++ 工程,或者您可以直接使用Sample中的RustDev项目。

5、将rust项目中dist目录下的全部文件拷贝到ArkUI-X Native C++跨平台工程的entry/libs目录下。同时在该libs目录下新建一个oh-package.json5文件,并加入以下内容:

{
  "name": "librust_add.so",
  "version": "1.0.0",
  "description": "Rust implementation of librust_add",
  "main": "librust_add.so"
}

6、在ArkUI-X Native C++跨平台工程的entry目录下的oh-package.json5文件中添加依赖配置,即在"dependencies"字段中加入以下内容:

"librust_add.so": "file:./libs"

效果如下:

随后点击"Sync Now"按钮同步项目,若entry/oh_modules目录内容如下图所示,即代表添加librust_add.so依赖成功。

7、在ArkUI-X Native C++跨平台工程的entry/src/main/ets/pages目录下的Index.ets文件中,引用librust_add.so文件,即可调用rust函数,可参考以下代码:

import { add } from "librust_add.so"

@Entry
@Component
struct Index {
  @State message: string = 'Hello Rust'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)

        Button() {
          Text('10 + 20')
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
        }.type(ButtonType.Capsule)
        .margin({ top: 20 })
        .backgroundColor('#0D9FFB')
        .width('35%')
        .height('5%')
        .onClick(()=>{
          this.message = "Result: " + add(10, 20);
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}

8、构建ArkUI-X Native C++跨平台工程即可。


三、ArkUI-X(iOS)如何调用rust

环境

1、编辑 .cargo目录中的config.toml文件,加入以下内容:

运行 where cargo 命令即可找到 .cargo目录位置

[target.aarch64-apple-ios]  # iPhone 真机 (ARM64)
ar = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar"
linker = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
rustflags = [
    "-C", "rpath=yes"
]

[target.x86_64-apple-ios]  # 模拟器 (Intel)
ar = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar"
linker = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
rustflags = [
    "-C", "rpath=yes"
]

[target.aarch64-apple-ios-sim]  # 模拟器 (Apple Silicon)
ar = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar"
linker = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
rustflags = [
    "-C", "rpath=yes"
]

编译

1、使用ohrs来创建一个新的rust项目,或者您可以直接使用Sample中的rust_add项目:

ohrs init rust_add

2、修改rust工程中的build.rs文件为如下内容:

use std::env;
use std::path::Path;

fn main() {
    napi_build_ohos::setup();
    // 指定某个源文件如果有修改就重新编译
    println!("cargo:rerun-if-changed=src/lib.rs");

    // 鸿蒙 构建配置
    if env::var("OHOS_BUILD").is_ok() {
        return;
    }

	// 获取目标平台架构,如 aarch64-linux-android
    let target = env::var("TARGET").unwrap_or_default();

    // Android 构建配置
    if target.contains("android") {
    	let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
        let arch_folder = match arch.as_str() {
            "aarch64" => "arm64-v8a",
            "arm"     => "armeabi-v7a",
            "x86_64"  => "x86_64",
            other => panic!("Unsupported Android architecture: {}", other),
        };

		// 根据项目的实际目录进行修改
        let lib_path = Path::new("../RustDev/.arkui-x/android/app/libs/")
            .join(arch_folder);

        println!("cargo:rustc-link-search=native={}", lib_path.display());
    	println!("cargo:rustc-link-lib=arkui_android");
    }

    // iOS 构建配置
    if target.contains("apple") {
    	// 获取项目根目录的路径
        let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
        // 根据项目的实际目录进行修改
        let framework_dir = Path::new(&manifest_dir)
            .join("../RustDev/.arkui-x/ios/frameworks/libarkui_ios.xcframework");

        let platform_subdir = if target.contains("sim") {
            "ios-arm64_x86_64-simulator"
        } else {
            "ios-arm64"
        };
        let framework_path = framework_dir.join(platform_subdir);

		// 输出路径(基于项目结构的相对路径生成的)
        println!("cargo:rustc-link-search=framework={}", framework_path.display());
        println!("cargo:rustc-link-lib=framework=libarkui_ios");
        println!("cargo:rustc-link-lib=framework=JavaScriptCore");
        println!("cargo:rustc-link-lib=framework=CoreFoundation");
        println!("cargo:rustc-link-lib=framework=UIKit");
    }
}

3、使用鸿蒙开发工具DevEco创建一个ArkUI-X Native C++ 工程,推荐将工程名设置为RustDev,并修改相应文件,详情见:鸿蒙上如何调用rust中编译的第7步。或者您可以直接使用Sample中的RustDev项目。

注意:您需要确保ArkUI-X Native C++ 工程与上面使用的rust工程处在同一目录下,因为在rust配置文件中使用了相对路径的形式来配置ArkUI-X工程中的xcframework文件位置,推荐将ArkUI-X工程名设置为RustDev也是出于同样的原因

4、使用DevEco打开ArkUI-X工程,点击菜单上的构建->编译Hap(s)/APP(s)->编译APP(s)按钮,以同步信息与xcframework动态库到ArkUI-X跨平台工程的iOS工程中。

5、进入rust工程中,编译target为iOS的.dylib文件,并将.dylib文件编译为.xcframework文件:

以下的命令均是在rust_add工程目录下执行的

(1)编译.dylib文件:

# 编译iOS真机.dylib文件
cargo build --target aarch64-apple-ios --release

# 编译iOS模拟器.dylib文件
cargo build --target aarch64-apple-ios-sim --release

动态库生成的位置:rust工程/target/aarch64-apple-ios/release/librust_add.dylib

(2)为.dylib文件设置加载路径:

# iOS真机
install_name_tool -id "@rpath/librust_add.framework/librust_add" target/aarch64-apple-ios/release/librust_add.dylib

# iOS模拟器
install_name_tool -id "@rpath/librust_add.framework/librust_add" target/aarch64-apple-ios-sim/release/librust_add.dylib

(3)生成framework文件:

# 创建iOS真机framework
mkdir -p framework/librust_add.framework
# 将iOS真机的dylib复制到相应的librust_add.framework文件夹内
cp target/aarch64-apple-ios/release/librust_add.dylib framework/librust_add.framework/librust_add

# 创建iOS模拟器framework
mkdir -p framework/sim/librust_add.framework
# 将iOS模拟器的dylib复制到相应的librust_add.framework文件夹内
cp target/aarch64-apple-ios-sim/release/librust_add.dylib framework/sim/librust_add.framework/librust_add

(4)分别在两个librust_add.framework文件夹内创建Info.plist文件,两个librust_add.framework文件夹的位置:rust工程/framework。然后添加以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleIdentifier</key>
	<string>ohos.ace.librustadd</string>
	<key>CFBundleVersion</key>
	<string>1.0.0</string>
	<key>CFBundleExecutable</key>
	<string>librust_add</string>
	<key>CFBundlePackageType</key>
	<string>FMWK</string>
	<key>CFBundleDevelopmentRegion</key>
	<string>en</string>
	<key>CFBundleDisplayName</key>
	<string>librust_add</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleShortVersionString</key>
	<string>6.0.0</string>
	<key>ClangVersion</key>
	<string>b'clang version 14.0.0'</string>
	<key>MiniXEngineVerson</key>
	<string>1.0.0</string>
	<key>MinimumOSVersion</key>
	<string>10.0</string>
</dict>
</plist>

注意:需要使用xcrun vtool -show-build path_for_dylib命令查看生成的librust_add.dylib适配的iOS版本,MinimumOSVersion设置的版本不能低于dylib最低支持版本。

ios_xcrun_vtool_show_build

(5)生成xcframework文件:

xcodebuild -create-xcframework -framework framework/librust_add.framework -framework framework/sim/librust_add.framework -output librust_add.xcframework

备注:在iOS工程中引入的libarkui_ios.xcframework与rust依赖的libarkui_ios.xcframework必须是同一个。

5、拷贝编译生成的librust_add.xcframework到ArkUI-X工程目录中:ArkUI-X工程/.arkui-x/ios/frameworks

6、将.arkui-x/ios/frameworks目录的librust_add.xcframework文件添加到iOS的工程的Frameworks目录当中,以导入动态库。

7、打开项目的TARGETS,点击General 之后下拉至Frameworks,Libraries,and Embedded Content。找到librust_add.xcframework,Embed选项修改为Embed&Sign(原为Do Not Embed)。

8、再次构建跨平台工程即可。


四、ArkUI-X(Android)如何调用rust

环境

1、配置Android NDK环境变量(以Android NDK版本28.0.13004108和CMake版本3.31.6为例)

Mac端

export ANDROID_NDK_HOME=/Android SDK路径/ndk/28.0.13004108

Windows端

需要在环境变量中配置,如下图:

变量:ANDROID_NDK_HOME 值:/Android SDK路径/ndk/28.0.13004108

2、使用Android NDK(Native Development Kit)生成一个独立的工具链

该步骤仅需Mac端配置

# aarch64-linux-android
python3 /Android SDK路径/ndk/28.0.13004108/build/tools/make_standalone_toolchain.py --api 30 --arch arm64 --install-dir 自定义路径/arm64

# armv7-linux-androideabi
python3 /Android SDK路径/ndk/28.0.13004108/build/tools/make_standalone_toolchain.py --api 30 --arch arm --install-dir 自定义路径/arm

# x86_64-linux-android
python3 /Android SDK路径/ndk/28.0.13004108/build/tools/make_standalone_toolchain.py  --api 30 --arch x86_64 --install-dir 自定义路径/x86_64

3、编辑 .cargo目录中的config.toml文件,加入以下内容

运行 where cargo 命令即可找到 .cargo目录位置

Mac端

以下为api设置为27版本时添加的配置内容:

[target.aarch64-linux-android]
ar = "生成的独立工具链路径/arm64/bin/llvm-ar"
linker = "生成的独立工具链路径/arm64/bin/aarch64-linux-android-clang"

[target.armv7-linux-androideabi]
ar = "生成的独立工具链路径/arm/bin/llvm-ar"
linker = "生成的独立工具链路径/arm/bin/arm-linux-androideabi-clang"

[target.x86_64-linux-android]
ar = "生成的独立工具链路径/x86_64/bin/llvm-ar"
linker = "生成的独立工具链路径/x86_64/bin/x86_64-linux-android-clang"

以下为api设置为30版本时添加的配置内容:

如果生成的工具链中没有aarch64-linux-android-ar等ar文件,则可以使用llvm-ar,例如:ar = "生成的独立工具链路径/arm64/bin/llvm-ar"

[target.aarch64-linux-android]
ar = "生成的独立工具链路径/arm64/bin/aarch64-linux-android-ar"
linker = "生成的独立工具链路径/arm64/bin/aarch64-linux-android-clang"

[target.armv7-linux-androideabi]
ar = "生成的独立工具链路径/arm/bin/arm-linux-androideabi-ar"
linker = "生成的独立工具链路径/arm/bin/arm-linux-androideabi-clang"

[target.i686-linux-android]
ar = "生成的独立工具链路径/x86/bin/i686-linux-android-ar"
linker = "生成的独立工具链路径/x86/bin/i686-linux-android-clang"

Windows端

[target.aarch64-linux-android]
ar = "Android SDK路径/ndk/28.0.13004108/toolchains/llvm/prebuilt/windows-x86_64/bin/llvm-ar"
linker = "Android SDK路径/ndk/28.0.13004108/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android35-clang.cmd"

[target.armv7-linux-androideabi]
ar = "Android SDK路径/ndk/28.0.13004108/toolchains/llvm/prebuilt/windows-x86_64/bin/llvm-ar"
linker = "Android SDK路径/ndk/28.0.13004108/toolchains/llvm/prebuilt/windows-x86_64/bin/armv7a-linux-androideabi35-clang.cmd"

[target.x86_64-linux-android]
ar = "Android SDK路径/ndk/28.0.13004108/toolchains/llvm/prebuilt/windows-x86_64/bin/llvm-ar"
linker = "Android SDK路径/ndk/28.0.13004108/toolchains/llvm/prebuilt/windows-x86_64/bin/x86_64-linux-android35-clang.cmd"

编译

1、使用ohrs来创建一个新的rust项目,或者您可以直接使用Sample中的rust_add项目:

ohrs init rust_add

2、修改rust工程中的build.rs文件为如下内容:参考代码

3、使用鸿蒙开发工具DevEco创建一个ArkUI-X Native C++ 工程,推荐将工程名设置为RustDev,并修改相应文件,详情见:鸿蒙上如何调用rust中编译的第7步。或者您可以直接使用Sample中的RustDev项目。

注意:您需要确保ArkUI-X Native C++ 工程与上面使用的rust工程处在同一目录下,因为在rust配置文件中使用了相对路径的形式来配置ArkUI-X工程中的so文件位置,推荐将ArkUI-X工程名设置为RustDev也是出于同样的原因

4、使用DevEco打开ArkUI-X跨平台工程,点击菜单上的构建->编译Hap(s)/APP(s)->编译APP(s)按钮,以同步信息与动态库到ArkUI-X跨平台工程的Android工程中。

5、进入rust工程中,编译target为Android 的.so文件:

cargo build --target aarch64-linux-android --release

动态库生成的目录:rust工程/target/aarch64-linux-android/release/librust_add.so

备注:在Android工程中引入的libarkui_android.so与rust依赖的libarkui_android.so必须是一致的。

6、拷贝rust生成的librust_add.so到ArkUI-X工程目录:ArkUI-X工程/.arkui-x/android/app/libs/arm64-v8a

7、再次构建跨平台工程即可。


五、添加Rust方法

1、打开rust工程,在lib.rs中添加新方法,例如:

#[napi]
pub fn subtract(left: i32, right: i32) -> i32 {
  left - right
}

2、重新使用ohrs来构建项目:

ohrs build

将rust项目中dist目录下的东西全部拷贝到libs目录下进行替换。

3、在ArkUI-X工程中添加subtract方法的调用,并打印返回结果。

4、使用DevEco打开ArkUI-X跨平台工程,点击菜单上的构建->编译Hap(s)/APP(s)->编译APP(s)按钮,以同步信息与动态库到ArkUI-X跨平台工程中。

5、重新编译rust工程:

Android平台

cargo build --target aarch64-linux-android --release

iOS平台

cargo build --target aarch64-apple-ios --release

6、将生成的动态库拷贝到ArkUI-X工程中的对应位置替换原来的rust动态库。

7、再次构建跨平台工程即可。

相关权限

不涉及

依赖

不涉及

约束与限制

1.本示例仅支持标准Android/iOS/鸿蒙系统上运行。

2.本示例已适配API version 20版本的ArkUI-X SDK,版本号:5.1.0.61及以上。

3.本示例需要使用DevEco Studio 5.0.4 Release (Build Version: 5.0.11.100, built on March 28, 2025) 及以上版本才可编译运行。

下载

如需单独下载本工程,执行如下命令:

git init
git config core.sparsecheckout true
echo /RustFeature/Rust > .git/info/sparse-checkout
git remote add origin https://gitcode.com/arkui-x/samples.git
git pull origin master