Why doesn't `cargo clean` have a way to specify feature flags?

As far as I know, most artifacts are specific to the feature-set for which they were built; when building the same project twice with different features, very few, if any, of the original build artifacts can be used for incremental compilation.

So, why doesn't cargo clean provide a way to restrict which artifacts are cleaned by feature-flags, the same way it permits specifying a specific profile to clean?

(Note: I think, ideally, I'd want to be able to specify feature-flag configurations not to clean, i.e. which artifacts to keep.)

I'm surprised I can't find any existing discussion of this here or elsewhere, so possibly I've done a poor job searching, or possibly there's some obvious reason that I haven't thought of.

Every feature is, technically, specific to a single package. The main reason that changing features can cause large rebuilds is that building some library crate with different features requires rebuilding all of its dependents with that modified library (even if the dependents don't interact with the effect that feature is documented to have).

The question I have in response is: for what purpose do you want this? If you are trying to reclaim disk space, I think that:

  • The long-term plan is to do this via a garbage collection strategy (removing unused artifacts) rather than explicit selection of what is deleted.
  • Most people use cargo clean and rebuild from scratch for this purpose.

This would actually be the more feasible way for such a feature to work. Picking a configuration and deleting everything used in that configuration would generally end up deleting artifacts that are shared, thus requiring rebuilding of all dependents.

It’s also more or less the same as having a automatic garbage collection mechanism, just invoked as "now immediately delete everything but what I just used".

cargo clean -p name blindly cleans all content related to that name and doesn't support the Package Id Spec synatx for being more specific (like clearing a specific version of windows-sys. This is because it doesn't know anything more! Same would apply to features.

Right now it is really bad in that intermediate build artifacts are organized by content type, so we have to do globs in each folder. With the upcoming build-dir changes, they will all be in build/name/hash which makes it easier but we'd still have to walk into each hash folder and load data (data that we don't yet track) to know which to delete.

We will be adding a db to track these for GC (after the build-dir changes). Maybe we can use that to do queries but this still adds a lot of complexity that would have to be outweighed by the benefits and I assume the benefit is a lot less wit GC.

2 Likes

Yes, the lack of garbage collection is the only reason I want such a feature.

This is orthogonal to my point about incremental build artifacts, isn't it?

Suppose you have, in your workspace,

  • package foo with no features
  • package bar with feature f1, which depends on foo regardless of that feature

Then if you run the hypothetical "pick a feature configuration and delete all artifacts used by that configuration" version of cargo clean,

$ cargo clean --features=f1
$ cargo build

the clean would delete foo’s artifacts since it is part of the dependencies of bar with that configuration, even though you can use it again in the following build without f1 (because it is unaffected by the presence or absence of f1).