今天要在昨天的模板中加入 Makefile
來幫助我們更好地使用 Rust 提供的各種開發工具,所以附上因為過度使用 make
吸收太多 M 能量而進化成魔人普烏的小螃蟹 Ferris (我到底在說什麼哈哈哈):
安裝 Rust 程式語言的同時會安裝好幾個重要的工具和程式,它們在開發和管理 Rust 項目中扮演著關鍵的角色。
其中每個工具都可以獨當一面,現在結合於一身,根本就是超級武器霸王,程式語言界的要你命 3000!
以下將簡單介紹這些工具,並提供一些範例,以更好地理解它們的作用。
rustc
- Rust 的官方編譯器。
它的主要職責是將 Rust 程式碼轉換為機器碼,以便在不同平台上運行。
讓我們看一個簡單的範例,首先在 main.rs
中輸入以下程式碼:
fn main() {
println!("Hello, Rust!");
}
接著就可以使用 rustc
將上面的程式碼編譯成可執行文件:
rustc main.rs
然後運行生成的可執行文件 ./main
,它將輸出 "Hello, Rust!"。
rustfmt
- Rust 程式碼格式化工具。
用於自動調整和統一 Rust 程式碼的風格,以使程式碼更易於閱讀並符合慣例。
例如我們有以下程式碼:
fn main() {println!("Hello, Rust!");}
運行 rustfmt
就能將其自動調整為更易於閱讀的格式。
rustup
- Rust 工具鏈管理器。
用於安裝和管理不同版本的 Rust 工具鏈的工具。
這對於在多個 Rust 專案之間切換或在不同 Rust 版本之間運行程式碼非常有用。
前幾天已經示範過如何使用 rustup
安裝 Rust。
clippy
- Rust 的 Linter。
用於檢查 Rust 程式碼中的潛在問題和風格問題,並提供改進建議。
假設有一個名為 main.rs
的 Rust 原始碼文件:
fn main() {
let mut my_string = "Hello, World".to_string();
my_string.push_str("!");
println!("{}", my_string);
}
透過 clippy 檢查後可能會生成類似以下的輸出:
warning: you seem to be trying to use a string literal to build a `String`. Consider using the `to_string` method to create a `String` from a string literal.
--> src/main.rs:2:24
|
2 | let mut my_string = "Hello, World".to_string();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unnecessary use of `String::push_str`
--> src/main.rs:3:5
|
3 | my_string.push_str("!");
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(clippy::string_lit_as_bytes)]` on by default
= note: `#[warn(clippy::string_add)]` on by default
在這個範例中,clippy 檢測到了兩個警告:
to_string
方法來從字符串文字創建 String。push_str
是不必要的,因為它附加一個字符串文字而不是 String 變量。遵循 clippy 的建議,我們可以改進程式碼,減少潛在的問題並提高程式碼品質。
cargo
- Rust 的 Package manager 和 Build tool。
是我們最常會用到的工具,它將上面的各項工具整合,讓我們能更輕鬆地創建、構建、測試和發布 Rust 專案。
以下是一些常見的 cargo 命令及其詳細說明:
cargo new <project_name>
:用於創建一個新的 Rust 專案。cargo build
:用於構建 Rust 專案。cargo run
:用於構建和運行 Rust 專案。cargo test
:用於運行 Rust 項目的測試套件。cargo fmt
:使用前面介紹的 rustfmt
,使不同開發者的程式碼風格保持一致。cargo clippy
:使用前面介紹的 clippy
,旨在檢測程式碼中的潛在問題、錯誤和不良實踐。cargo check
:用於快速檢查 Rust 專案的程式碼,不需要進行完整的編譯和構建。cargo update
:用於將專案的依賴函式庫更新至最新版本。cargo publish
:若是正在開發 Rust 函式庫,這個命令可以把函式庫發布到 crates.io (Rust 的官方套件託管中心)。總的來說,cargo
是 Rust 開發的核心工具之一,它使得管理依賴函式庫、構建程式碼、運行測試等工作變得簡單且高效。
為了更好地利用上面介紹的工具,我們可以把開發常見的流程與指令整合在 Makefile
中,進一步提升我們的工作效率。
而今天我們要加到模板中的 Makefile
內容如下:
.PHONY: version run test format lint release all
# Define ANSI escape codes for colors and formatting
RESET_COLOR = \033[0m
BOLD = \033[1m
RED = \033[91m
GREEN = \033[92m
YELLOW = \033[93m
BLUE = \033[94m
version:
@echo "$(BOLD)Rust CLI Versions:$(RESET_COLOR)"
@echo "------------------"
@echo "$(BLUE)rustc (compiler):$(RESET_COLOR) $$(rustc --version | sed 's/rustc //' | tr -d '\n')"
@echo "$(BLUE)cargo (package manager):$(RESET_COLOR) $$(cargo --version | sed 's/cargo //' | tr -d '\n')"
@echo "$(BLUE)rustfmt (code formatter):$(RESET_COLOR) $$(rustfmt --version | sed 's/rustfmt //' | tr -d '\n')"
@echo "$(BLUE)clippy (linter):$(RESET_COLOR) $$(clippy-driver --version | sed 's/clippy //' | tr -d '\n')"
@echo "$(BLUE)rustup (toolchain manager):$(RESET_COLOR) $$(rustup --version 2>/dev/null | sed 's/rustup //' | tr -d '\n')"
format:
@echo "$(BLUE)$(BOLD)Formatting code...$(RESET_COLOR)"
@cargo fmt --quiet
lint:
@echo "$(YELLOW)$(BOLD) Running linter...$(RESET_COLOR)"
@cargo clippy --quiet
test:
@echo "$(GREEN)$(BOLD) Running Rust tests...$(RESET_COLOR)"
@cargo test --quiet 2>&1 | \
grep -E '^test result' | \
sed 's/^/ /' | \
sed -E 's/(ok)/\x1b[32m\1\x1b[0m/g; s/(FAILED)/\x1b[31m\1\x1b[0m/g'
run:
@echo "$(RED)$(BOLD)Running the Rust program...$(RESET_COLOR)"
@cargo run --quiet
release:
@echo "$(BOLD)Building in release mode...$(RESET_COLOR)"
@cargo build --release
all: format lint test run
@echo "$(RESET_COLOR)$(BOLD)All tasks completed.$(RESET_COLOR)"
讓我們分解這個 Makefile
的主要部件:
.PHONY
.PHONY
是 Makefile
中的一個特殊目標 (target),用於聲明某些目標為 "虛擬"(phony) 的,也就是說它們不代表實際的文件名。Makefile
仍會執行相應的命令。RESET_COLOR
、BOLD
、RED
、GREEN
、YELLOW
和 BLUE
都屬於此類轉義碼。Makefile
中都對應於一個特定的任務或操作,可以通過執行 make
命令並指定目標名稱來執行。version
:使用彩色輸出顯示各種與 Rust 相關的工具的版本信息。format
:運行 cargo fmt
命令來格式化 Rust 程式碼。lint
:運行 cargo clippy
命令對 Rust 程式碼執行檢查。test
:使用 cargo test
命令執行 Rust 測試,並使其縮排與以彩色輸出測試結果。run
:使用 cargo run
命令運行 Rust 程序並顯示其輸出。release
:使用 cargo build --release
命令以發布模式構建 Rust 項目。all
:是一個元目標,它依賴於 format
、lint
、test
和 run
,實際上會依序執行這些操作,並在最後顯示一條消息表示所有任務已完成。命令之前的
@
符號用於抑制在終端中顯示命令本身,確保只顯示輸出結果。
將 Makefile
加入模板之後,已經可以用它來開啟每個專案了,流程如下:
cargo init --name=<...>
原地初始化新專案,這裡以 cargo init --name=hello-world
為例,此時資料夾結構如下:
.
├── .devcontainer
│ ├── devcontainer.json
│ └── Dockerfile
├── Makefile
├── Cargo.toml
├── src
│ └── main.rs
└── setup.sh
也可以用
cargo new
建立新專案,並cd
進去,但要記得把Makefile
放進生成的資料夾中。
make all
測試一下我們的 Makefile
:make version
看看各個工具的版本:總的來說,這個 Makefile
提供了一個方便的方式來管理和自動化 Rust 專案中的常見任務,如格式化、檢查、測試、運行以及以發布模式構建專案,並使用彩色文本輸出提供了用戶友好和視覺上吸引人的界面。
今天我們在模板中加入了 Makefile
,它可以幫助我們節省時間,並確保每個操作都按照預期運行。
尤其是 make all
中的流程確保了程式碼的可讀性、可維護性、可靠性和性能。
經常執行這些工作並解決問題可以幫助減少錯誤,提高程式碼品質,並維護良好的程式碼基礎。
在 MLOps 中持續整合 (Continuous Integration) 也是很重要的一環,所以明天我們要以此為基礎設定 GitHub Action。
明天見啦!