# Rust App 开发基本设置
我们将在macOS上进行Rust App跨平台开发,以下的设置都是基于macOS。
## Rust 安装
### 安装rustup
Rust 提供了友好的开发工具链,我们只需要先安装`rustup`, 通过`rustup`便可完成Rust 语言开发环境的安装和配置。
```bash=
> curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
### 安装rust-1.41
PayBy 需要兼容32位iOS系统,而Rust从1.42开始不再支持iOS 32位架构,所以我们选择安装1.41.0 版本。
```bash=
> rustup install 1.41.0
> rustup default 1.41.0
```
安装完成后,可以检查当前生效的Rust编译器版本:
```bash=
> rustc --version
rustc 1.41.0 (5e1a79984 2020-01-27)
```
### 安装Cargo
Cargo是Rust的包管理器,类似于Java的Maven,Gradle等。使用下面等命令安装:
```bash=
> curl https://sh.rustup.rs -sSf | sh
```
## App 编译目标平台设置
为了让Rust编译器编译出适合在Android和iOS上使用的库,需要添加相应的`targets`支持。`rustup` 能够帮我们搞定。另外还需要为不同平台添加相应的工具链支持。
### Android 平台设置
#### 添加targets
```bash=
> rustup target add aarch64-linux-android \
armv7-linux-androideabi \
i686-linux-android \
x86_64-linux-android
```
#### NDK 工具链
确保正确安装了 Android NDK tools,并且设置好了`NDK_HOME`系统环境变量。
有了正确的`NDK_HOME`后,我们只需要安装`cargo-ndk`, 就可以让Rust查找到
正确的NDK链接器,并在Rust和Android NDK之间进行正确的转换,最终产出Android
平台上可用的NDK 库。
我们只需要使用Cargo 就可以方便安装 `cargo-ndk`:
```bash=
> cargo install cargo-ndk --version 1.0.0
```
### 添加 iOS targets
```bash=
> rustup target add aarch64-apple-ios \
armv7-apple-ios \
armv7s-apple-ios \
x86_64-apple-ios \
i386-apple-ios
```
### iOS 工具链
为了生成iOS项目需要的头文件,需要安装 `cbindgen`:
```bash=
> cargo install cbindgen --version 0.15.0
```
为了自动生成universal库文件,需要安装`cargo-lipo`:
```bash=
> cargo install cargo-lipo --version 3.1.1
```
## 跨平台开发项目结构
我们的目标是,核心业务逻辑使用Rust编写,节约工作量,并保持业务逻辑的一致性;
在核心业务逻辑之上,通过薄薄的一层绑定,适配到 iOS和Android。
所以我们的项目结构可以划分为:
```bash=
payby_logic
|
|-- features
|-- feature_1
|-- feature_x
|-- binding
|-- Android
|-- iOS
```
当然,各个核心逻辑是可以单独构成项目,通过Rust的`crate`机制集成。
### 构建脚本
为了方便构建,避免重复命令,分别编写 `android_build.sh`:
```bash=
#!/usr/bin/env bash
# set the version to use the library
min_ver=21
# verify before executing this that you have the proper targets installed
cargo ndk --target aarch64-linux-android --android-platform ${min_ver} -- build --release -p binding_payby_android
cargo ndk --target armv7-linux-androideabi --android-platform ${min_ver} -- build --release -p binding_payby_android
cargo ndk --target i686-linux-android --android-platform ${min_ver} -- build --release -p binding_payby_android
cargo ndk --target x86_64-linux-android --android-platform ${min_ver} -- build --release -p binding_payby_android
# moving libraries to the android project
jniLibs=./outputs/android
libName=libbinding_payby_android.so
rm -rf ${jniLibs}
mkdir -p ${jniLibs}
mkdir -p ${jniLibs}/arm64-v8a
mkdir -p ${jniLibs}/armeabi-v7a
mkdir -p ${jniLibs}/x86
mkdir -p ${jniLibs}/x86_64
cp target/aarch64-linux-android/release/${libName} ${jniLibs}/arm64-v8a/${libName}
cp target/armv7-linux-androideabi/release/${libName} ${jniLibs}/armeabi-v7a/${libName}
cp target/i686-linux-android/release/${libName} ${jniLibs}/x86/${libName}
cp target/x86_64-linux-android/release/${libName} ${jniLibs}/x86_64/${libName}
```
以及 `ios_build.sh`:
```bash=
#!/usr/bin/env bash
iosLibs=./outputs/ios
libName=libbinding_payby_ios
rm -fr ${iosLibs}
mkdir -p ${iosLibs}
# cbindgen create .h file
cbindgen --crate binding_payby_ios -o ${iosLibs}/${libName}.h
cargo lipo --all --release --targets=aarch64-apple-ios,x86_64-apple-ios,armv7-apple-ios,armv7s-apple-ios
mkdir -p ${iosLibs}/aarch64-apple-ios
mkdir -p ${iosLibs}/armv7-apple-ios
mkdir -p ${iosLibs}/armv7s-apple-ios
mkdir -p ${iosLibs}/x86_64-apple-ios
mkdir -p ${iosLibs}/universal
cp target/aarch64-apple-ios/release/${libName}.a ${iosLibs}/aarch64-apple-ios/${libName}.a
cp target/armv7-apple-ios/release/${libName}.a ${iosLibs}/armv7-apple-ios/${libName}.a
cp target/armv7s-apple-ios/release/${libName}.a ${iosLibs}/armv7s-apple-ios/${libName}.a
cp target/x86_64-apple-ios/release/${libName}.a ${iosLibs}/x86_64-apple-ios/${libName}.a
cp target/universal/release/${libName}.a ${iosLibs}/universal/${libName}.a
```
至此,Rust App 跨平台开发基本的设置就完成了,接下来我们就可以愉快地进行Rust开发了。
## 参考
- <https://robertohuertas.com/2019/10/27/rust-for-android-ios-flutter/>
- <https://doc.rust-lang.org/cargo/>
- <https://doc.rust-lang.org/book/>