【问题标题】:Conditional compilation for Rust build.rs script?Rust build.rs 脚本的条件编译?
【发布时间】:2019-08-09 07:08:36
【问题描述】:

Rust 语言支持使用#[cfg(test)] 等属性的conditional compilation。 Rust 还支持 build scripts 使用 build.rs 文件来运行代码作为构建过程的一部分以准备编译。

我想在 Rust 代码中使用条件编译来根据我们是否为构建脚本进行编译来进行条件编译,类似于 test 构建的方式。

想象一下:

#[cfg(build)]
fn main() {
    // Part of build script
}

#[cfg(not(build))]
fn main() {
    // Not part of build script, probably regular build
}

这不起作用,因为build 在这里不是有效的标识符。 是否可以使用不同的属性来做到这一点,或者是否可以使用其他技巧来实现类似的效果?


关于这个问题的一些背景:
我的目标是在编译时通过clap 生成shell 完成脚本。我在应用程序中的多个文件中有一个相当全面的App 定义。我想在build.rs 中使用它,通过使用include!(...) 宏(如suggested by clap)包含这些部分,所以我不必再次定义App。这会带来一些依赖关系,我想在 build.rs 文件使用时排除这些依赖关系,因为在这种情况下不需要它们。 This 是我试图在我的 build.rs 脚本中提供的内容。

【问题讨论】:

  • 我们是否正在为构建脚本进行编译——这没有意义。构建脚本仅包含在一个特殊文件中(例如build.rs)。没有其他可以编译的上下文。
  • 感谢您的回答。我将解释我想在什么情况下使用它:它用于在编译时通过clap 生成 shell 完成脚本。我对多个文件(在主应用程序中)有相当全面的App 定义。我想将其拉入build.rs 以生成定义。这会带来一些依赖关系,我想在 build.rs 文件使用时排除这些依赖关系。 (建议:docs.rs/clap/2.32.0/clap/struct.App.html#examples-47)(我要使用的:github.com/timvisee/ffsend/blob/master/src/cmd/handler.rs#L51
  • 当 build.rs 文件使用时我想排除它 - 为什么?无论如何,您都必须为主应用程序构建这些
  • 这需要我定义不少dev-dependencies。除此之外,感觉没有必要包含build.rs 脚本中未涵盖的大量代码。我相信脚本应该尽可能简单,而不需要引入整个主应用程序。我想避免再次定义App,并希望防止重复代码。

标签: rust conditional-compilation


【解决方案1】:

您可以将构建代码放在 build.rs 中(或者可能让 build.rs 声明一个 mod xyz 以拉入另一个文件)。

我想知道您要问的问题是您是否可以从 build.rs 和 main.rs 引用相同的代码,如果可以,该代码是否可以判断它是否被其中一个或另一个调用。似乎您可以在使用 build.rs 时打开环境变量集(使用类似 option_env 的东西,但更好的方法可能是在 build.rs 中启用主代码中的功能。

(如果您还没有阅读,请阅读the documentation for build scripts。)

【讨论】:

  • 您可以在构建时启用功能,例如,将以下行 println!("cargo:rustc-cfg=feature=\"build-time\"") 放入 build.rs:main。但范围不同。它只影响当前的 crate,而不影响依赖项(有关更多信息,请参阅github.com/rust-lang/cargo/issues/5499)。此外,如果您以这种方式启用功能,它也会在构建结果(bin、lib)中启用。所以,在这种情况下它没有帮助。
  • 这确实是一种处理方式,但感觉有点笨拙。我宁愿为build.rs 脚​​本提供一个额外的功能,而不是相反。但我认为没有办法指示编译器这样做。 build.rs 脚本中的任何逻辑只有在编译它(并拉入应用程序源)后才会被评估。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多