Simply Patrick

建置 Jupyter Notebook 的 Rust 運作環境

最近重新安裝了 macOS Big Sur,也順便想試試 Jupyter Notebook 的 Rust 運作環境,再加上這幾天放假比較有時間,就把安裝的過程記錄下來。

安裝 Miniconda

過去一直覺得 Anaconda 有點肥大,所以這次決定先從安裝比較精簡的 miniconda 開始:

$ brew install --cask miniconda

新增 conda-forge channel 等下才能安裝一些需要的套件如 jupyterlab:

$ conda config --add channels conda-forge
$ conda config --set channel_priority strict

然後需要初始化 conda 的 base 環境,一般都是跑 conda init,但它會加一段不是很通用的設定到我個人的 .zshrc,我不是很喜歡這種做法,所以就先只套用在目前的 shell 裡:

$ eval `conda shell.zsh hook`

創建新的 conda 環境

創建一個新的環境叫 rust-notebook:

(base) $ conda create -n rust-notebook python=3
(base) $ conda activate rust-notebook

安裝 JupyterLab

在新的環境指定安裝 jupyterlab 版本 2.2.9,因為最新的 3.0 似乎與最新的 jupyterlab-plotly 不相容:

(rust-notebook) $ conda install jupyterlab=2.2.9

然後安裝 jupyterlab-plotly:

(rust-notebook) $ jupyter labextension install jupyterlab-plotly

安裝 evcxr_jupyter

這邊假設 Rust 已經安裝完成,直接用 Cargo 安裝 Rust 的 Jupyter kernel:

$ cargo install evcxr_jupyter
$ evcxr_jupyter --install

啟動 JupyterLab:

(rust-notebook) $ jupyter lab

如果可以看到下列 Rust 圖樣應該就是成功了:

範例執行結果

試一下:

println!("Hello, Jupyter!");
Hello, Jupyter!

來畫個圖:

:dep plotters = { git = "https://github.com/38/plotters", default_features = false, features = ["evcxr", "line_series"] }
extern crate plotters;
use plotters::prelude::*;
use plotters::series::*;

let figure = evcxr_figure((640, 480), |root| {
    root.fill(&WHITE);
    let mut chart = ChartBuilder::on(&root)
        .caption("y=x^2", ("Arial", 50).into_font())
        .margin(5)
        .x_label_area_size(30)
        .y_label_area_size(30)
        .build_ranged(-1f32..1f32, -0.1f32..1f32)?;

    chart.configure_mesh().draw()?;

    chart.draw_series(LineSeries::new(
        (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)),
        &RED,
    )).unwrap()
        .label("y = x^2")
        .legend(|(x,y)| PathElement::new(vec![(x,y), (x + 20,y)], &RED));

    chart.configure_series_labels()
        .background_style(&WHITE.mix(0.8))
        .border_style(&BLACK)
        .draw()?;
    Ok(())
});
figure
y=x^2 0.0 0.2 0.4 0.6 0.8 -0.8 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 y = x^2

參考


看 log 的好工具: klogg

工作上常需要看 log 解決問題,推薦一個好用的工具 klogg:


Setup Fuchsia Rust Development on macOS

基本上照著官方的指引 Rust Editor Configuration,設置 Fuchsia OS 開發的 Rust 開發環境主要就兩個步驟:

  1. 產生 Cargo.toml
  2. 設定編輯器使用 Rust 的 Language Server (RLS)

產生 Cargo.toml

很簡單,就是用 fx gen-cargo //garnet/foo/path/to/target:label 產生對應的 Cargo.toml。例如 fx gen-cargo //garnet/bin/log_listener:bin 會產生 /garnet/bin/log_listener/Cargo.toml

設定 RLS

官方文檔提到要先把 Fuchsia 自帶的 Rust 連結到 rustup,並且設成預設的 toolchain:

$ rustup toolchain link fuchsia /<your Fuchsia root>/buildtools/<platform>/rust
$ rustup default fuchsia

我是有做第一步,但第二步我比較持保留態度,之後試過似乎不做也沒影響,我會建議跳過這一步。

Vim

跟 C++ 類似,只是 Language Server 我們必須從 clangd 換成 RLS,所以可以在 Vim 裡用 :CocInstall coc-rls 來安裝 coc-rls extension,如果你系統之前就有裝過 RLS 的話,在 Vim 裡打開對應的目錄就會有 code completion 的功能了。

如果你的系統沒有 RLS 或你覺得用 Fuchsia 自帶的 Rust toolchain 比較保險,可以用 :CocConfig 把下列設定加進去:

{
  "rust.target": "x86_64-fuchsia",
  "rust.target_dir": "/<your Fuchsia root>/out/cargo_target",
  "rust.unstable_features": true,
  "rust-client.rlsPath": "/<your Fuchsia root>/buildtools/<platform>/rust/bin/rls",
  "rust-client.disableRustup": true,

  // Some optional settings that may help:
  "rust.goto_def_racer_fallback": true,
  "rust-client.logToFile": true,
}

Visual Studio Code

VSCode 則是需要安裝 Rust (rls) 這個 plugin。同樣如果你的系統沒有 RLS 或你覺得用 Fuchsia 自帶的 Rust toolchain 比較保險,加入下列的設定到 VS Code 裡:

{
  "rust.target": "x86_64-fuchsia",
  "rust.target_dir": "/<your Fuchsia root>/out/cargo_target",
  "rust.unstable_features": true,
  "rust-client.rlsPath": "/<your Fuchsia root>/buildtools/<platform>/rust/bin/rls",
  "rust-client.disableRustup": true,

  // Some optional settings that may help:
  "rust.goto_def_racer_fallback": true,
  "rust-client.logToFile": true,
}

Setup Fuchsia C++ Development on macOS

關於 Fuchsia

Fuchsia 是 Google 開發中的新作業系統,它的底層原始碼可以到 https://fuchsia.googlesource.com 公開下載。雖然 Google 對外宣稱 Fuchsia 是個實驗性質的專案,但蠻多人認為它有潛力成為 Google 的大一統 OS,慢慢取代掉 Android 或 Chrome OS,姑且不論這是否會發生,對於喜歡研究系統軟體或嵌入式軟體技術的開發人員,Fuchsia 可以讓你一窺如何打造一個現代化的 OS。

Fuchsia 的開發環境

目前 Fuchsia OS 可以在 Linux 或 macOS 上編譯,這篇主要是分享在 macOS 上建置 C++ 的 OS 開發環境的經驗,包括:

  • 基本的編輯器 (Vim 及 Visual Studio Code) 設置
  • Code completion 的設置
  • 使用 direnv 來實現設置自動化

編輯器選擇

我的環境建置基本是根據這份官方提供的 C++ Editor/IDE Setup 指南,裡面有提到 CLion, Vim, 以及 Visual Studio Code,試用過後個人推薦 Vim > VS Code » CLion,主要還是因為個人開發時通常只會需要修改全部 code base 的極小一部份,小巧的編輯器使用體驗會比較流暢,也不會耗用太多的機器資源去處理不會修改的部份。

而開發必備的 code completion 功能,個人推薦使用 compilation database + clangd 的設置。

Vim 設置

Vim 版本

推薦使用 Vim >= 8.1 或是最新的 Neovim (我目前用 v0.3.7)。

FUCHSIA_DIRfuchsia.vim

Fuchsia 預設提供了一些 Vim 專用的設定,在 ~/.vimrc 裡套用這些設定的修改如下:

if $FUCHSIA_DIR != ""
  source $FUCHSIA_DIR/scripts/vim/fuchsia.vim
endif

我不喜歡每次手動設置 export FUCHSIA_DIR=/path/to/fuchsia-dir,也不喜歡直接修改 ~/.bashrc,所以用 direnv (直接用 Homebrew 安裝) 在進目錄時自動套用設定。

path/to/fuchsia-dir/.envrc 加入:

# For VIM to find fuchsia.vim
export FUCHSIA_DIR=`pwd`

之後 cd 進去就會幫你把 FUCHSIA_DIR 的環境變量設定好了。

Code Completion 設置

前置準備

確認 fx build 是成功的,然後使用 fx compdb 產生 compile_commands.json

Language Server clangd

同樣利用 direnv 來套用 PATH 的修改,因此新增這一行到 path/to/fuchsia-dir/.envrc :

export PATH=$FUCHSIA_DIR/buildtools/mac-x64/clang/bin:$PATH

目的是讓 Vim 優先使用 Fuchsia 自帶的 clangd,否則使用其他版本的 clangd 可能會有 C++ 編譯的問題產生。

Conquer of Completion (CoC)

因為 YCM 其實有點肥大,安裝上也比較麻煩,我現在比較喜歡用 Coc,Coc 的詳細配置可以參考 How to Set Up Code-Completion for Vim in macOS

基本上在 Vim 裡執行 :CocConfig 把以下配置填上應該就行了。

{
  "languageserver": {
    "clangd": {
      "command": "clangd",
      "rootPatterns": ["compile_flags.txt", "compile_commands.json", ".vim/", ".git/", ".hg/"],
      "filetypes": ["c", "cc", "cpp", "objc", "objcpp"]
    }
  }
}

Visual Studio Code 設置

VS Code 設置上比較簡單,基本上只要把 vscode-clangd 安裝起來並確保 Fuchsia 自帶的 clangd 可以在 PATH 裡找到就可以用了。使用速度上雖然比起 Vim 遲鈍了一些,但整體流暢度還是可是在我可以接受的範圍。


Learning Rust

關於 Rust

會知道 Rust 是因為之前公司團隊的工作是跟瀏覽器引擎 (Webkit/Blink) 的優化有關,那時只知道 Mozilla 正在用 Rust 這個新的程式語言實驗性地開發 Servo 引擎。同時間 Go 已經到達 1.0 的里程碑,同時有著優異的編譯及執行效能,很快地 Go 就變成我個人主要使用的程式語言,工作上需要的一些小工具也都是用 Go 來實現。

開始對 Rust 重新關注大概是它在 2015 年釋放 1.0 版本後,那時只稍微了解一下語法及主要的語言特性,當時覺得這程式語言的學習曲線蠻陡峭的,必須全面地對所有的語言特性有一定了解後才能駕馭它。那時 Go 用的正是順手,所以就沒什麼動力把 Rust 完整學起來。

去年開始工作上需要了解 Fuchsia OS 的實作,赫然發現裡面蠻多系統服務都是用 Rust 開發的,數量上甚至比 Google 自家的 Go 還多,這也是我決定多投入時間學習 Rust 的轉捩點。

學習資源

我主要使用下列幾本書來學習 Rust:

  • 深入浅出 Rust 這本書的電子版: 它的特色是側重於解釋 Rust 主要概念的設計思想,而不只是單純語法或用法的說明;且因為是中文的緣故,讀起來速度還是比較快,比較像是 Rust 的內功心法入門。
  • 30 天深入淺出 Rust 系列 則是以淺顯易懂的範例把 Rust 主要的特色講解了一遍,內容適合對於想要快速地對 Rust 有個全面性的概觀的人。
  • 對 Rust 有了基本的了解後,A Gentle Introduction to Rust 則是適合有 C/C++ 經驗的開發者來學習如何寫 idiomatic Rust。

至於最經典的 The Rust Programming Language 呢? 我只把了一些我覺得重要的章節看完,其他剩下的就直接動手實作,遇到有細節不清楚或是已經忘記時再花時間來看。

其他資源

上面主要是比較完整的 Rust 學習資源,下一篇再分享一些我覺得不錯的 blog post,通常是針對某個特定主題或進階功能的解釋或教學。