1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

cargoの条件付きコンパイルを試す

Posted at

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 - The Cargo Book

ちなみに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_NAMEbuild.rs実行時に未設定のため利用することができませんでした。代わりにbuild.rsで利用できる環境変数があります。
何かの参考になれば幸いです。

  1. 簡単なコードならtodo!()で実現できます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?