Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional compilation for Rust build.rs script?

The Rust language supports conditional compilation using attributes like #[cfg(test)]. Rust also supports build scripts using a build.rs file to run code as part of the build process to prepare for compilation.

I would like to use conditional compilation in Rust code to conditionally compile depending on whether we're compiling for a build script, similar to how that is possible for test builds.

Imagine the following:

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

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

This does not work, because build is not a valid identifier here. Is it possible to do this using a different attribute, or could some other trick be used to achieve something similar?


For some context on this issue:
My goal is to generate shell completion scripts through clap at compile time. I've quite a comprehensive App definition across multiple files in the application. I'd like to use this in build.rs by including these parts using the include!(...) macro (as suggested by clap), so I don't have to define App a second time. This pulls some dependencies with it, which I'd like to exclude when used by the build.rs file as they aren't needed in that case. This is what I'm trying to make available in my build.rs script.

like image 848
Tim Visée Avatar asked Mar 18 '19 20:03

Tim Visée


People also ask

Where do I put build RS files?

Placing a file named build.rs in the root of a package will cause Cargo to compile that script and execute it just before building the package.

What is a build script?

A build script is a file that is started by a build plan. The build script prepares output from generated files.

How does Cargo work rust?

Cargo is the Rust package manager. Cargo downloads your Rust package's dependencies, compiles your packages, makes distributable packages, and uploads them to crates.io, the Rust community's package registry.

What does Cargo build do?

Cargo resolves all dependencies of your project, downloads missing dependencies, and compiles it using the rustc compiler. By default, projects are built and compiled in debug mode. For information on compiling your project in release mode, see Building a Rust project in release mode. An existing Rust project.


1 Answers

You can just put the build code in build.rs (or presumably have build.rs declare a mod xyz to pull in another file).

I wonder if the question you are trying to ask is whether you can reference the same code from build.rs and main.rs, and if so can that code tell if it's being called by one or the other. It seems you could switch on an environment variable set when using build.rs (using something like option_env, but possibly a nicer way might be to enable a feature in the main code from within build.rs.

(Have a read of the documentation for build scripts if you haven't already.)

like image 169
Squirrel Avatar answered Nov 14 '22 17:11

Squirrel