如何构建具有相同配置选项的二进制文件和库?
How to build a binary and a library with the same configuration options?
截至发问时,如果您在同一个 cargo 项目中有一个 bin 和一个 lib,并且想使用特定的 rustc cfg 选项构建 bin 和 lib,那是行不通的。
您可以使用 rustc cfg 选项构建一个或另一个,但不能同时构建两个。如果您尝试构建 lib,然后在编译 bin 时构建 bin,它会在没有 rustc 选项的情况下重新编译 lib。
有没有办法做到这两点,如果不能,为什么?我注定要创建自己的构建脚本吗?如果是这样,那有什么意义?
编辑
好吧,也许我有点戏剧化
Background/Expansion
假设我有类似的东西:
src/lib.rs
pub mod mylib {
#[cfg(not(dosomething))]
pub use self::without_cfg::dosomething;
#[cfg(dosomething)]
pub use self::with_cfg::dosomething;
mod with_cfg {
pub fn dosomething() {
println!("config option");
}
}
mod without_cfg {
pub fn dosomething() {
println!("no config option");
}
}
}
src/main.rs
extern crate modules;
use modules::mylib::dosomething;
fn main() {
dosomething();
}
因此,如果我使用 dosomething 的 cfg 选项进行编译,我将获得函数的一个版本,但如果我没有配置,我将获得“默认”行为或其他任何行为。
现在,如果我尝试使用 cargo rustc 进行编译,我将永远无法获得在 lib 中设置了 cfg dosomething 的 bin 版本。
我最接近能够在货物中完成所有操作的是:
cargo rustc -v --lib -- --cfg dosomething
cargo rustc -v --bin [bin name] -- --cfg dosomething
第一个命令将使用 cfg 编译 lib,但第二个命令使用 重新编译 没有 cfg 的 lib 以创建 bin。
我想到的唯一解决方法是:
cargo rustc -v --bin [bin name] -- --cfg dosomething
复制命令编译的内容,例如:
rustc src/main.rs --crate-name [bin name] --crate-type bin -g --cfg dosomething --out-dir [/path/to/project]/target/debug --emit=dep-info,link -L dependency=[/path/to/project]/target/debug -L dependency=[/path/to/project]/target/debug/deps --extern modules=[/path/to/project]/target/debug/libmodules.rlib`
然后 运行:
cargo rustc -v --lib -- --cfg dosomething
最后复制并粘贴之前的 rustc 命令,以便使用设置了 cfg 选项的库编译 bin。
这是唯一的方法吗?为什么我不能以某种方式指定哪个 libs/bins 获得我想要的 rustc cfg 选项,即使它在 Cargo.toml 中?还是我和我都没有意识到?
对于那些问...
Cargo.toml:
[package]
name = "[bin name]"
version = "0.1.0"
authors = ["[Me] <[my email]>"]
[lib]
name = "modules"
path = "src/lib.rs"
P.S。感谢所有从事 rust 和 cargo 工作的人,总而言之,我发现这是一个愉快的工作环境,并且热爱这门语言。继续努力。
如果我理解正确,那么 Cargos features 应该能帮上忙:
src/lib.rs
#[cfg(feature = "dosomething")]
pub use self::with_cfg::dosomething;
#[cfg(not(feature = "dosomething"))]
pub use self::without_cfg::dosomething;
#[cfg(feature = "dosomething")]
mod with_cfg {
pub fn dosomething() {
println!("config option");
}
}
#[cfg(not(feature = "dosomething"))]
mod without_cfg {
pub fn dosomething() {
println!("no config option");
}
}
src/main.rs
extern crate what;
use what::dosomething;
fn main() {
dosomething();
}
Cargo.toml
[package]
name = "what"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
[features]
dosomething = []
现在,当我可以在任一模式下编译或 运行 时:
$ cargo run
Compiling what v0.1.0 (file:///private/tmp/what)
Running `target/debug/what`
no config option
$ cargo run --features dosomething
Compiling what v0.1.0 (file:///private/tmp/what)
Running `target/debug/what`
config option
截至发问时,如果您在同一个 cargo 项目中有一个 bin 和一个 lib,并且想使用特定的 rustc cfg 选项构建 bin 和 lib,那是行不通的。
您可以使用 rustc cfg 选项构建一个或另一个,但不能同时构建两个。如果您尝试构建 lib,然后在编译 bin 时构建 bin,它会在没有 rustc 选项的情况下重新编译 lib。
有没有办法做到这两点,如果不能,为什么?我注定要创建自己的构建脚本吗?如果是这样,那有什么意义?
编辑
好吧,也许我有点戏剧化
Background/Expansion
假设我有类似的东西:
src/lib.rs
pub mod mylib {
#[cfg(not(dosomething))]
pub use self::without_cfg::dosomething;
#[cfg(dosomething)]
pub use self::with_cfg::dosomething;
mod with_cfg {
pub fn dosomething() {
println!("config option");
}
}
mod without_cfg {
pub fn dosomething() {
println!("no config option");
}
}
}
src/main.rs
extern crate modules;
use modules::mylib::dosomething;
fn main() {
dosomething();
}
因此,如果我使用 dosomething 的 cfg 选项进行编译,我将获得函数的一个版本,但如果我没有配置,我将获得“默认”行为或其他任何行为。
现在,如果我尝试使用 cargo rustc 进行编译,我将永远无法获得在 lib 中设置了 cfg dosomething 的 bin 版本。
我最接近能够在货物中完成所有操作的是:
cargo rustc -v --lib -- --cfg dosomething
cargo rustc -v --bin [bin name] -- --cfg dosomething
第一个命令将使用 cfg 编译 lib,但第二个命令使用 重新编译 没有 cfg 的 lib 以创建 bin。
我想到的唯一解决方法是:
cargo rustc -v --bin [bin name] -- --cfg dosomething
复制命令编译的内容,例如:
rustc src/main.rs --crate-name [bin name] --crate-type bin -g --cfg dosomething --out-dir [/path/to/project]/target/debug --emit=dep-info,link -L dependency=[/path/to/project]/target/debug -L dependency=[/path/to/project]/target/debug/deps --extern modules=[/path/to/project]/target/debug/libmodules.rlib`
然后 运行:
cargo rustc -v --lib -- --cfg dosomething
最后复制并粘贴之前的 rustc 命令,以便使用设置了 cfg 选项的库编译 bin。
这是唯一的方法吗?为什么我不能以某种方式指定哪个 libs/bins 获得我想要的 rustc cfg 选项,即使它在 Cargo.toml 中?还是我和我都没有意识到?
对于那些问...
Cargo.toml:
[package]
name = "[bin name]"
version = "0.1.0"
authors = ["[Me] <[my email]>"]
[lib]
name = "modules"
path = "src/lib.rs"
P.S。感谢所有从事 rust 和 cargo 工作的人,总而言之,我发现这是一个愉快的工作环境,并且热爱这门语言。继续努力。
如果我理解正确,那么 Cargos features 应该能帮上忙:
src/lib.rs
#[cfg(feature = "dosomething")]
pub use self::with_cfg::dosomething;
#[cfg(not(feature = "dosomething"))]
pub use self::without_cfg::dosomething;
#[cfg(feature = "dosomething")]
mod with_cfg {
pub fn dosomething() {
println!("config option");
}
}
#[cfg(not(feature = "dosomething"))]
mod without_cfg {
pub fn dosomething() {
println!("no config option");
}
}
src/main.rs
extern crate what;
use what::dosomething;
fn main() {
dosomething();
}
Cargo.toml
[package]
name = "what"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
[features]
dosomething = []
现在,当我可以在任一模式下编译或 运行 时:
$ cargo run
Compiling what v0.1.0 (file:///private/tmp/what)
Running `target/debug/what`
no config option
$ cargo run --features dosomething
Compiling what v0.1.0 (file:///private/tmp/what)
Running `target/debug/what`
config option