条件付きコンパイルについて。
専用の分岐方法がいくつかある。
cfg マクロ
条件によって true か false の値になる。
以下では、OS ごとに通常の if 文で分岐している。
fn main() {
println!("I am using '{}'.", os_name());
}
fn os_name() -> &'static str {
if cfg!(target_os = "ios") {
"iOS"
} else if cfg!(target_os = "macos") {
"macOS"
} else {
"non-Apple OS"
}
}
cfg 属性条件によって直後のコードブロックのコンパイル有無を変更する。
以下では、OS ごとに実装コードを分けている。
fn main() {
println!("I am using '{}'.", os_name());
}
fn os_name() -> &'static str {
#[cfg(target_os = "ios")]
return "iOS";
#[cfg(target_os = "macos")]
return "macOS";
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
return "non-Apple OS";
}
cfg_attr 属性条件によって直後のコードブロックへの属性の適用有無を変更する。
以下では、OS ごとに実装ファイルを分けている。
#[cfg_attr(target_os = "ios", path = "ios.rs")]
#[cfg_attr(target_os = "macos", path = "macos.rs")]
#[cfg_attr(not(any(target_os = "ios", target_os = "macos")), path = "os.rs")]
mod os;
fn main() {
println!("I am using '{}'.", os::os_name());
}
pub fn os_name() -> &'static str {
"iOS"
}
pub fn os_name() -> &'static str {
"macOS"
}
pub fn os_name() -> &'static str {
"non-Apple OS"
}
専用の分岐フラグが多数用意されている。
構成オプションにはキーのみのものとキーと値からなるものがある。
以下はそれらの抜粋 (詳細は公式資料を参照)。
testdebug_assertionsunixtarget_family = "unix" と等価windowstarget_family = "windows" と等価feature = "value"target_os = "value"target_family = "value"target_endian = "value"target_pointer_width = "value"
feature は条件として使える独自定義できる変数である。
クレートが対応する feature の値は cargo.toml ファイルで定義できる。
フィーチャーはネストでき、あるフィーチャを有効にするとその配下も有効になる。
デフォルトで有効にしたいフィーチャーは default フィーチャーの配下にする。
[package]
name = "my_crate"
version = "0.1.0"
[features]
default = ["feature1"]
feature1 = []
feature2 = ["feature2_1", "feature2_2"]
feature2_1 = []
feature2_2 = []
feature3 = ["feature3_1", "feature3_2"]
feature3_1 = []
feature3_2 = []
cargo build に実行オプションを指定する。デフォルトのフィーチャーが不要なら --no-default-features を、全てのフィーチャーが必要なら --all-features を、個別指定するには --features "feature1 feature2" のようにする。
または、.cargo/config.toml ファイルの rustflags の項目を指定する。なお、rustflags の親項目は全体設定用の build の他に target 系があり、それらでは構成に応じたフィーチャの導入も可能 (詳しくは config.toml の公式資料を参照)。
[build]
rustflags = ["--cfg", "feature2", "feature3"]
config.toml ファイルで他クレートのフィーチャーを指定する。これには、他クレートへの依存と同時に記述する方法、そして自クレートのフィーチャーを他クレートのフィーチャと連携させる方法がある。
[package]
name = "my_app"
version = "0.1.0"
[dependencies]
extenal_crate1 = { version = "0.1.0", default-features=false }
extenal_crate2 = { version = "0.1.0", default-features=true }
[dev-dependencies]
extenal_crate3 = { version = "0.1.0", features=["deep_test"] }
[features]
default = ["my_feature"]
my_feature = ["extenal_crate2/additional_feature"]