『条件付きコンパイル』を使えば、no_std
環境に対応しつつ、かつ std
環境ではより便利になるクレートを作成できる。ここではサンプルを通してその作成手順を紹介する。
cargo.toml
ファイル以下は関係する項目。
package.categories
crates.io などでクレートの検索に使われるカテゴリを指定する。
no_std 環境用の値には no-std
や no-std::no-alloc
がある。
package.metadata.docs.rs
Docs.rs における rustdoc
コマンドの引数を指定する。
詳しくは『rustdoc でのフィーチャーの表示』を参照。
features
条件付きコンパイルのためのフィーチャーを定義する。よく見かける設定は、標準環境用のフィーチャー std
をデフォルトとして作り、その配下をヒープメモリのためのフィーチャ alloc
などで細分化していくパターンである。
[package]
name = "my_crate"
version = "0.1.0"
categories = ["no-std"]
[package.metadata.docs.rs]
rustdoc-args = ["--cfg", "docsrs"]
[features]
default = ["std"]
std = ["alloc"]
alloc = []
lib.rs
ファイル以下が必要になる場合が多い。
std
クレートをデフォルトで無効化
#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(feature = "std")] extern crate std;
#[cfg(feature = "alloc")] extern crate alloc;
// ... //
条件付きコンパイルを利用した各アイテムを記載する。
以下では、関数 print_box
はフィーチャー alloc
の有効時にのみ使用できる。
pub fn print_val<T: std::fmt::Display>(arg: T) {
println!("{arg}")
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
pub fn print_box<T: std::fmt::Display>(arg: Box<T>) {
println!("`{0}` at '{0:p}'", arg);
}
以下でも、関数 print_box
はフィーチャー alloc
の有効時にのみ使用できる。
なお、ここでの path
属性はファイル階層を少し分かりやすくする狙いがある。
mod print_basic;
pub use print_basic::*;
#[doc(hidden)]
#[cfg(feature = "alloc")]
#[path = ""]
mod with_alloc {
mod print_etc;
pub use print_etc::*;
}
#[cfg(feature = "alloc")]
pub use with_alloc::*;
pub fn print_val<T: std::fmt::Display>(arg: T) {
println!("{arg}")
}
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
pub fn print_box<T: std::fmt::Display>(arg: Box<T>) {
println!("`{0}` at '{0:p}'", arg);
}