Rust 2018开发环境配置与开发效率工具集

文档列表见: Rust 移动端跨平台复杂图形渲染项目开发系列总结(目录)

一句话概括: macOS/Linux用户首选CLion + Rust插件,折腾VSCode收益太低 。以下内容来自参与开发 gfx-rs/halgfx-rs/wgpu 等Rust主流开源图形项目时所作尝试的总结。

配置Rust编译环境

使用Rust开发macOS、iOS、Android等跨平台共享源码的项目,开发环境避免不了这些系统所要求的开发环境,即:

  • macOS、iOS需要安装Xcode
  • Android需要Android Studio、Android SDK、Android NDK,并且配置SDK、NDK到环境变量。 如果不想手工配置SDK、NDK变量,对于macOS,推荐先安装Android Studio到Application,之后通过Android Studio安装Android SDK、NDK,然后向profile、zsh配置文件等写入SDK、NDK变量。
  • 修改Rust软件更新源为中科大站点对国内用户而言可以提高下载速度,已翻墙可不考虑。
    // 1. 打开环境变量配置文件
    vi ~/.bashrc
    // 2. 加入如下内容
    export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static
    export RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup
    // 3. 激活新配置内容
    source ~/.bashrc
    复制代码
  1. 安装Rsut,如果要安装nightly编译工具链才加 --channel=nightly 根据朋友反馈,2018年11月21日用下面的中科大源安装会报错,官方源没问题。
    // 以下命令二选一
    // 中科大源
    curl -sSf https://mirrors.ustc.edu.cn/rust-static/rustup.sh | 
    sh # -s -- --channel=nightly
    // 官方源
    curl https://sh.rustup.rs -sSf | sh
    复制代码
  2. cargo环境变量设置 当前版本的cargo装好后,并不自动设置环境变量。在此进行手动配置,方便后面使用cargo安装的效率工具。在此以macOS为例,mac上的cargo一般安装在 ~/.cargo/bin 下。
    export CARGO_BIN="[你的HOME目录]/.cargo/bin"
    export PATH="$PATH:$CARGO_BIN"
    复制代码

IDE配置

CLion与推荐插件

  • Rust插件 提供代码提示、补全、跳转等功能,比Rust Language Server(RLS)稳定、好用,插件功能的更新速度快
  • Toml 方便编写 Cargo.toml 文件
  • Active Intellij Tab Hightlighter 高亮当前打开的Tab页
  • Dash 查文档方便
  • Git Conflict 在源文件中用颜色区分代码冲突,比Intellij系列产品原生做法更直观
  • Grep Console 过滤控制台输出,比默认功能更强
  • HighlightBracketPair 高亮显示光标所在的区域,比如在某个 {}()[] 内。

不推荐Visual Studio Code的原因

RLS不稳定导致代码跳转经常失效是最重要的原因,但是,VSCode的优势是,在无法代码跳转的情况下还能提供比CLion更强的代码提示,这让我感到意外。

另外,VSCode配置起来麻烦,对Rust新手不友好。

提高开发维护效率的工具集

CI配置appveyor与travis

  1. appveyor配置文件 appveyor.yml
    language: rust
    sudo: false
    
    matrix:
      include:
    
      - rust: stable
        script:
        - cargo test --all --locked
        - rustup component add rustfmt-preview
        - cargo fmt -- --write-mode=diff
    复制代码
  2. travis配置文件 .travis.yml
    language: rust
    rust:
      - stable
      - nightly
    
    branches:
      except:
        - staging.tmp
    
    before_install:
      # Do not run bors builds against the nightly compiler.
      # We want to find out about nightly bugs, so they're done in master, but we don't block on them.
      - if [[ $TRAVIS_RUST_VERSION == "nightly" && $TRAVIS_BRANCH == "staging" ]]; then exit; fi
    
    script:
      - cargo test
      - cargo build #--manifest-path your_project_path/Cargo.toml --features remote
      - cargo build
      #- (cd examples && make) #TODO
    复制代码

cbindgen 给Rust代码自动生成C头文件

给iOS/Android等编写跨平台C++/Rust项目最终还是以C接口方式让外部使用,当提供较多接口时,手写容易出错、开发慢,此时用自动头文件生成器是更合理的选择,cbindgen可帮我们实现这一目标。

  1. 安装 cargo install cbindgen
  2. 更新cbindgen cargo install --force cbindgen
  3. 使用方式一:命令行执行
    cbindgen crate/ -o crate/bindings.h
    复制代码
  4. 使用方式一:作为项目的预处理使用方式写成 build.rs ,对于复杂项目,推荐用此方案
    extern crate cbindgen;
    
    use std::env;
    
    fn main() {
        let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    
        cbindgen::Builder::new()
          .with_crate(crate_dir)
          .generate()
          .expect("Unable to generate bindings")
          .write_to_file("bindings.h");
    }
    复制代码

bindgen 给C头文件生成Rust绑定代码

和cbindgen相反,bindgen可生成Rust调用C函数所需的FFI绑定代码,但是这个工具在遇到多重包含如 #include "other_file.h" 时会出错,详细说明见官方文档。

  1. 安装 cargo install bindgen
  2. 使用 bindgen input.h -o bindings.rs
    • --rust-target 指定Rust版本,如 --rust-target 1.30
    • --rust-target nightly 使用nightly工具链

sccahe 多工作区共享编译缓存

目前Rust只支持工作区workspace内部多个项目间的编译缓存,不支持workspace之间的缓存。对于多个workspace引用了部分相同版本的组件,这花费了多余的编译时间,没意义。借助第三方工具 sccahe 可解决此问题。

cargo install sccache
export RUSTC_WRAPPER=sccache

rustfmt 统一代码风格

为避免无意义的风格争论,推荐使用Rust官方出品的统一代码风格组件 rustfmt 。以下所有命令都需要在已配置好Rust环境的终端上执行。

rustup component add rustfmt-preview
rustup update
cargo fmt

自定义rustfmt代码风格

不建议自定义代码风格,最好和官方默认代码保持一致。定制风格规则参考 rustfmt#configuring-rustfmt

用built输出Rust项目构建信息

built 是个编译依赖(dev-dependencies)的开源项目,详细用法见项目说明。

  1. 配置Cargo.toml

    [dev-dependencies]
    built = "*"
    复制代码
  2. 使用示例

    pub mod built_info {
        include!(concat!(env!("OUT_DIR"), "/built.rs"));
    }
    
    info!("This is version {}{}, built for {} by {}.",
          built_info::PKG_VERSION,
          built_info::GIT_VERSION.map_or_else(|| "".to_owned(),
                                              |v| format!(" (git {})", v)),
          built_info::TARGET,
          built_info::RUSTC_VERSION);
    trace!("I was built with profile \"{}\", features \"{}\" on {} using {}",
           built_info::PROFILE,
           built_info::FEATURES_STR,
           built_info::BUILT_TIME_UTC,
           built_info::DEPENDENCIES_STR);
    复制代码

输出信息:

This is version 0.1.0 (git 62eb1e2), built for x86_64-apple-darwin
by rustc 1.16.0-nightly (bf6d7b665 2017-01-15).

I was built with profile "debug", features "DEFAULT, ERR_PRINTLN"
on Thu, 16 Feb 2017 19:00:08 GMT using android_glue 0.2.1,
ansi_term 0.9.0, bitflags 0.3.3, bitflags 0.4.0, bitflags 0.6.0,
bitflags 0.7.0, block 0.1.6, built 0.1.0, byteorder 0.5.3,
bytes 0.3.0, cfg-if 0.1.0, cgl 0.1.5, cgmath 0.7.0, ...
复制代码

Rust开发iOS项目的效率工具

cargo-lipo

cargo lipo 一个命令可编译出iOS目前支持的5个CPU架构静态库,且自动合并成一个多合一的universal静态库。

cargo install cargo-lipo
cargo lipo

Rust项目开启Bitcode编译

RUSTFLAGS="-C llvm-args=\"-fembed-bitcode\"" cargo build
复制代码

You can tell cargo to pass any argument you wish to the Rust compiler by setting the RUSTFLAGS environment variable. The Rustc compiler has a flag -C llvm-args=val that you can use to pass additional arguments to llvm.

参考: Enable Bitcode Output in Cargo Build for iOS Targets?

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章