Pitfalls when enabling features from build scripts

I have an edge case where I want to enable features based on whether an environment variable is set. How much trouble am I causing for Future Me if I do this?

A while back I tried this in a project. I don't remember the exact means, but if I recall correctly is was accomplished using something along the line of:

println!("cargo:rustc-cfg=feature=\"something\"");

The thing that bit me back then was the realization that at this point it's too late for the dependency resolver to do its thing, so it would not work if the feature had to add dependencies. It made me realize I might be venturing into some rather thin ice, so I gave up on the idea.

That said, I have seen crates that detect whether the compiler being used is stable or nightly, and it enables a "nightly" feature when using the nightly compiler, and this is somewhat closely related to what I want to do.

Let's say that that we confine ourselves to features without any dependencies -- how bad of an idea is it to enable features from a build script?

Yes. You can add a custom cfg with your own choice of name that is not feature, but you should not add a cfg=feature="something" precisely because features are expected to match what Cargo’s dependency resolver did.

This probably doesn’t apply to your situation, but auto-detecting nightly is bad practice, because

  • libraries that do this will break when the unstable feature is changed in some way, which may happen without notice, and
  • users build on nightly for a variety of reasons, which do not necessarily include wanting to use unstable functionality in the program being built.

Libraries should only use unstable features with explicit opt-in from the dependent, or when the library cannot work at all without them.

1 Like