最近重新安裝了 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(- 1 f32 ..1 f32 , - 0.1 f32 ..1 f32 )? ;
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 :
基本上照著官方的指引 Rust Editor Configuration ,設置 Fuchsia OS 開發的 Rust 開發環境主要就兩個步驟:
產生 Cargo.toml
設定編輯器使用 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 ,
}
關於 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_DIR
及 fuchsia.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 遲鈍了一些,但整體流暢度還是可是在我可以接受的範圍。
關於 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:
至於最經典的 The Rust Programming Language 呢? 我只把了一些我覺得重要的章節看完,其他剩下的就直接動手實作,遇到有細節不清楚或是已經忘記時再花時間來看。
其他資源
上面主要是比較完整的 Rust 學習資源,下一篇再分享一些我覺得不錯的 blog post,通常是針對某個特定主題或進階功能的解釋或教學。