cargoの条件付きコンパイルを簡単なケースで試してみました。
cargoは/src/bin
または/examples
配下のファイルを実行することができますが、クレート本体のコンパイルエラーで実行できない場合がありました。
コンパイルエラーは修正しないままに/src/bin
または/examples
のファイルを実行したく、本記事の内容を調べました。1
本記事で利用するRustのバージョンは1.82.0です。
$ rustc --version
rustc 1.82.0 (f6e511eec 2024-10-15)
$ cargo --version
cargo 1.82.0 (8f40fc59f 2024-08-21)
方法1:featuresを利用する
Cargo.tomlに下記を追記します。
[features]
wip = []
これで条件付きコンパイルに利用できるfeaturewip
を作成できましたので、下記のように利用できます。
fn main() {
#[cfg(feature = "wip")]
println!("something in wip feature.");
#[cfg(not(feature = "wip"))]
println!("something without wip feature.");
}
実行するときに、--features
フラグで指定します。
cargo run --features wip
# something in wip feature.
cargo run
# something without wip feature.
ちなみにfeaturesは下記のような目的で利用されているようでしたので、目的に沿ったものであれば違和感なく利用できると思います。
- ビルド時間とファイルサイズを最適化する
- ライブラリの機能を拡張する
-
no_std
属性を補助する - 依存関係を再公開する
- Cライブラリの依存先選択肢を提供する
- ライブラリの機能に優先度付けする
- 手続きマクロを分離する
- 実験的機能を分離する
参考:Features Examples - The Cargo Book
方法2:定義済みの環境変数を利用する
cargoプロジェクトのルートディレクトリに配置するbuild.rs
を利用します。
build.rs
はBuild Scriptsと呼ばれ、パッケージビルドが開始する前に実行されます。
build.rs
を作成し、下記を記述します。
fn main() {
// lintの`#[warn(unexpected_cfgs)]`を抑制する
println!("cargo::rustc-check-cfg=cfg(CUSTOM_VAR)");
// 変数が変更された場合のみBuild Scriptsを実行する
println!("cargo::rerun-if-env-changed=CUSTOM_VAR");
if std::env::var("CUSTOM_VAR").is_ok() {
println!("cargo::warning=Succeeded."); // 動作確認用
println!("cargo::rustc-cfg=CUSTOM_VAR");
} else {
println!("cargo::warning=Something is wrong."); //動作確認用
}
let mut file = File::create("example.txt").unwrap(); // 動作確認用
file.write_all(b"some text").unwrap(); // 動作確認用
}
参考:Build Scripts - The Cargo Book
これで環境変数CUSTOM_VAR
を下記のように利用できます。
fn main() {
#[cfg(CUSTOM_VAR)]
println!("CUSTOM_VAR is valid.");
#[cfg(not(CUSTOM_VAR))]
println!("CUSTOM_VAR is invalid.");
}
cargo run # CUSTOM_VAR is invalid.
# cargoコマンドの前に記述すると、その実行時のみ変数を設定できます
CUSTOM_VAR=1 cargo run # CUSTOM_VAR is valid.
cargo run # CUSTOM_VAR is invalid.
# シェル上で環境変数を宣言する
export CUSTOM_VAR=1
cargo run # CUSTOM_VAR is valid.
# 環境変数の値が同じなのでBuild Scriptsが再実行されません
cargo run # CUSTOM_VAR is valid.
unset CUSTOM_VAR
cargo run # CUSTOM_VAR is invalid.
ちなみに環境変数の宣言は.cargo/config.toml
を使っても可能でした。
cargoプロジェクトのルートディレクトリに.cargo/config.toml
を作成します。
下記でcargoが認識する形で環境変数を定義できます。ただしキャッシュが効いており、値を更新してもBuild Scriptsへは反映されませんでした。
[env]
CUSTOM_VAR="1"
参考:Configuration - The Cargo Book
あとがき
cargoで利用できる環境変数を調べるきっかけになりました。
ちなみにCARGO_BIN_NAME
はbuild.rs
実行時に未設定のため利用することができませんでした。代わりにbuild.rs
で利用できる環境変数があります。
何かの参考になれば幸いです。