1

通过一个例子学习Cargo Features

 1 year ago
source link: https://jasonkayzk.github.io/2022/11/28/%E9%80%9A%E8%BF%87%E4%B8%80%E4%B8%AA%E4%BE%8B%E5%AD%90%E5%AD%A6%E4%B9%A0Cargo-Features/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在C、C++中我们经常会使用#define、#ifdef等预处理指令进行条件编译,这样会提升编译速度、减少编译后文件大小,在某些场景下会非常有用;

例如:某些和具体平台实现相关的代码,在win平台下使用时,其实无需编译linux平台下的代码;

本文通过一个例子讲解了Cargo Features是如何实现的;

通过一个例子学习Cargo Features

前言

本文只是通过一个例子来讲解如何使用 Cargo Features,并非讲解 Cargo Features 的全部特性以及底层实现;

同时,在阅读本文之前,请先阅读:

对 Cargo Features 有一定的基础,再来学习本文;

实现一个含有feature的lib

和上面 条件编译 Features 的内容保持一致,在例子中会定义这么几个 feature:

[features]
bmp = []
png = []
ico = ["bmp", "png"]
webp = []

bmp、png、ico、webp,并且 ico 依赖 bmp 和 png 特性;

创建 feature-demo crate:

cargo new feature-demo --lib

修改 Cargo.toml,增加 feature 定义:

feature-demo/Cargo.toml

+ [features]

+ default = []

+ full = [
+     "bmp",
+     "png",
+     "ico",
+     "webp"
+ ]

+ bmp = []
+ png = []
+ ico = ["bmp", "png"]
+ webp = []

同时实现各个 feature:

// feature-demo/src/lib.rs
pub mod bmp;
pub mod ico;
pub mod png;
pub mod webp;

// feature-demo/src/bmp.rs
#[cfg(feature = "bmp")]
pub fn process_bmp() {
    println!("Processing bmp");
}

// feature-demo/src/png.rs
#[cfg(feature = "png")]
pub fn process_png() {
    println!("Processing png");
}

// feature-demo/src/webp.rs
#[cfg(feature = "webp")]
pub fn process_webp() {
    println!("Processing webp");
}

// feature-demo/src/ico.rs
use crate::bmp::process_bmp;
use crate::png::process_png;

#[cfg(all(feature = "png", feature = "bmp"))]
#[cfg(feature = "ico")]
pub fn process_ico() {
    println!("Before process_ico: ");
    process_bmp();
    process_png();
    println!("Processing ico")
}

各个文件中的内容如上所示,其中 #[cfg(...)] 的意思是,只有定义了这个 feature 才编译下面的代码;

关于 cfg:

同时,由于 ico 特性依赖 bmp、png 特性,因此需要先使用了 png、bmp 特性,同时使用了 ico 特性才会编译相应的代码;

至此,我们带有 feature 的 lib 编写完成;

使用一个含有feature的lib

下面来使用我们刚刚编写的含有 feature 的 lib;

首先引入这个 crate:

Cargo.toml

[dependencies]
feature-demo = { path = "./feature-demo", features = ["bmp", "ico"] }

这里引入了 bmp 和 ico 特性,但是由于 ico 特性依赖了 png 特性,因此实际上我们也是可以使用 png 特性的!

在 main 中使用这个 lib:

src/main.rs

use feature_demo::bmp::process_bmp;
use feature_demo::ico::process_ico;
use feature_demo::png::process_png;

fn main() {
    process_bmp();

    process_png();

    process_ico();
}

执行后输出:

Processing bmp
Processing png
Before process_ico: 
Processing bmp
Processing png
Processing ico

但是,由于我们没有引入 webp 特性,因此这部分代码实际上不会被编译,并且我们也无法使用!

例如,添加下面的代码,会造成编译失败:

use feature_demo::bmp::process_bmp;
use feature_demo::ico::process_ico;
use feature_demo::png::process_png;
+ use feature_demo::webp::process_webp;

fn main() {
    process_bmp();

    process_png();

    process_ico();
+
+    process_webp();
}

在添加了相关的 feature 之后,编译成功:

- feature-demo = { path = "./feature-demo", features = ["bmp", "ico"] }
+ feature-demo = { path = "./feature-demo", features = ["bmp", "ico", "webp"] }

附录

文章参考:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK