Repository navigation
Should build-plans be deleted? #7614
Description
Activity
FWIW, IntelliJ IDEA and rust-analyzer are only (atm) using build-plan to get the value of
OUT_DIR. If there were some other way to get at it (e.g. #7546), then they wouldn't have any reason to use it anymore.Reacted by Vlad Beskrovny, Edwin Cheng, Maximilian Goisser, Pauan, Tux3 and James LeitchI'm not the right person to cc for this, you should ping someone who works on Firefox
In IntelliJ Rust we use build-plan only to locate buildscript output directory (
env!("OUT_DIR")in build.rs) for each crate in the graph. The ability to locate these directories is critical (but not really enough) to support code generation in the IDE. So, I'd be happy with a replacement like #7546.(but in long-term, we need something like #7178 with the ability to get all outputs of all buildscripts in a dependency graph)
cc @Xanewok , I think build plans play a role in the non-cargo story for RLS.
I’ll write a bigger response once I am a the real keyboard, but in-short, my opinion is:
- OUT_DIR and build.rs produced cfgs should be communicated to the IDEs somehow
- build plan seems to be a conceptually wrong way to do this, +1 to removal (unless 3rd party build system integration benefits from build plans)
- I don’t know how a good solution for IDE problem should look like, current cargo semantics make this non-trivial
- given that IntelliJ already needs OUT_DIR, and rust-analyzer will need it “soon” (soon — someone has a spare weekend) it might make sense to prototype some replacement for the narrow IDE use-case. It’s ok if it’s nightly only.
The core problem is that IntelliJ Rust needs a way to get
OUT_DIR. They already implemented all the machinery for processinginclude!(concat!(env!("OUT_DIR"), "bindings.rs")). And handling such includes is important for user-experience of those who use code-generation.It would be great to have some replacement feature for sniffing
OUT_DIR. It doesn't have to be stable: tools have to track nightly for various reasons anyway.Ideally, this info should be a part of
cargo metadata, because IDEs really love the static picture of dependencies between the crates. Unfortunately, this can't work, because build scripts are fundamentally associated with units, and not with packages. That is,cargo buildandcargo build --releasewill use (I think) differentOUT_DIRs.Long-term, we probably should do something like #7178, and maybe even try to move to "build.rs per package", and not "build.rs per unit" model.
For the time being, I like @ehuss suggestion: #7546 (comment). Basically, we just include
OUT_DIRto the build-script json message, as if it printedcargo:rustc-env:OUT_DIR=/foo/bar. This seems like something we should just do. Should I send a PR ? :) This is forward compatible (and even a required part of) #7178. IntelliJ can then have a special UI action like "scrape build config", which is explicitly invoked by the user, runscargo build --message-format=jsonand fishes outOUT_DIR(and cfg as well). That's a pretty awkward UX, but it is much better than nothing at all.Just to give a better understanding of IDE requirements here, I believe the following small data-structure captures the information a Rust IDE needs pretty well:
It is much simpler than Cargo's internal representation, and the question is, how we lower Cargo's repr to this
CrateGraph.EDIT: PR to add OUT_DIR to
--message-format=json: #7622Reacted by Vlad Beskrovny and Benjamin BrittainNote also that IDE use-case seems to be over-represented in this issue, while the original and main motivation for build plan was integration with other build systems. Should we cc folks from Facebook or Google maybe?
Reacted by Crystal DurhamBasically, we just include
OUT_DIRto the build-script json message, as if it printedcargo:rustc-env:OUT_DIR=/foo/bar. This seems like something we should just do. Should I send a PR ? :)If that works for you. I'm not familiar with how rust-analyzer or intellij works. I would maybe just add a new key to the structure (
out_dir) instead of stuffing it in the env array (to avoid confusion about what the script sets vs what cargo sets).Reacted by Alex Kladov and Vlad Beskrovnycc @Xanewok , I think build plans play a role in the non-cargo story for RLS.
Yes, that's currently how our support for external build systems work. We parse the
--build-planoutput and do the compilation ourselves in the RLS.FWIW I tried to address the build plan integration and (by accident) #7178 while working on Buck integration in the PR #6213.
To generate a detailed build plan (where you only need to run
rustc) one had to run and parse the output of build scripts before a full, static build plan could be generated. The original motivation for that PR was to emit file dependencies per each unit but as it turns out that's also only available in the post-build-script phase, so that's what was implemented.We agreed with @alexcrichton then that approach from #6213 seemed too 'bolted-on' and would require more effort to get it right. Maybe now would be a good time to design together a better way forward? Until then, I think it'd be good not to outright remove delete them (maybe we could deprecate/destabilize it?) until we know how to proceed.
Thanks for all the responses everyone! With the merge of #7622 it sounds like we may be on good track to delete build plan support? I suspect that'll want to propagate through for a few weeks/cycles, but once all the tools switch over to that I believe we'll have no active users of the build plan support.
Reacted by Igor MatuszewskiReacted by Alex Kladov and Vlad Beskrovnycc @jsgf
Reacted by Jeremy FitzhardingeI have a pretty solid tool for generating Buck build rules from Cargo, and build plans have played no part in that. I did try to use them, but found the information was at the wrong level of abstraction.
I'm fine with removing build plans and trying again from scratch.
Reacted by Tyler MandryOk I'm going to set myself a TODO for ~2 months from now to delete build plans. In the meantime we can update documentation and such and make sure to comment on issues that the intention is to delete this feature.
There is a tool, I'm actively developing, that uses build plans - cargo-wharf.
The tool is an integration layer for BuildKit build system and effectively is "cargo in docker". It uses the build plan feature to construct a BuildKit graph.
It didn't get much attention yet, but I believe in its potential since I think many people might use Rust for creating async scalable microservices now. This often involves containerization and Docker is a popular choice.
Interesting enough, the current implementation and its limitation are perfectly fit into my use case. For instance, the independent (from Cargo) build scripts running made possible to have a system-wide build script results caching.
On the other hand, I understand that there is no reason to keep an unstable feature that is not being widely used. Especially if its maintenance often makes a hard time for contributors. For quite a while, I was under the impression that Cargo uses build plans internally.
Would it possibly make sense to gradually make Cargo to first generate a build plan and then only to execute it? Right now it probably won't give any benefits, but in the future, it might lead to interesting possibilities. I have a feeling the refactoring might also improve maintainability and testability of the Cargo code.
@denzp that was sort of the theory for build plans all along, but it never manifested. Build plans, as is today, are suitable to drive Cargo's own compilation. I think most here want to see a world where Cargo build plans exist, but the problem is that we're not there today and we don't have any manpower to actually make it a reality, so the team decided it's best to reflect reality and delete the build plan feature rather than let it linger and give the false impression that it will ever be stabilized near as-is.
59 remaining items
@elldritch you said you use build plans for
We're building a system to cache Cargo build outputs. One thing we rely on --build-plan for is knowing the OUT_DIR associated with executing each build script.
It would be good to dig into that more of the reason you even need to touch
OUT_DIR. While you are going about this a different way than the actual issue, #9661 has users similarly accessing it. If your use case is not covered in #9661 (comment), it might be good to create an issue to discuss your use case and explore how it should be solved.- added 3 commits that reference this issue
on Nov 5, 2025 - added a commit that references this issue
on Nov 6, 2025 Closed by #16212
This broke some custom tooling that wrapped builds and provided progress. The build plan was only used for progress total tracking (get how many 'steps' the build output would generate, then use that to manipulate the progress bar) when performing parallel builds of different architectures and configurations.
Is there any other way to get this information ahead of time? It's really unfortunate now that progress information will have to be removed; the tooling was really nice beforehand. The plans themselves (the commands, arguments, etc.) were not used directly; just the counts.
While it can't give you the progress information ahead of time...
for me this was the crucial feature of build plans: a way of establishing what actions the compiler would take, but not actually take them. in addition to #15844, are there any plans for implementing this kind of functionality?
Reacted by Josh Junon, Eliza Zhang and Eyal KalderonI used build plans to get kind and OUTDIR for each build-product to derive some complex codegen. Now I doing it in other way.
Reacted by Eliza ZhangIt's kind of unfortunate that
--build-planwas removed prior to a potential replacement set of flags (#15844) being in place :/ I have to pin the toolchain now, or spend a bunch of time migrating away from what looked like a stable option for something significantly less useful.Reacted by Eliza Zhang@Qix- please keep in mind that this is an unstable feature and has been under discussion for removal for 6 years.
That said, some thoughts on paths forward. In your case
- Long term, we want to provide plumbing commands, see https://github.com/crate-ci/cargo-plumbing which we called out in the proposal to close (Should build-plans be deleted? #7614 (comment))
- Would unit graph work? Eventually this will be encompassed in the plumbing commands but I see less reason to remove this until then though as we integrate plumbing commands, there might be shifts in this.
- I think we should work to improve our json messages. The build analysis work is one area that will help shine a light on that. Another is the new cargo-fix architecture which would ideally have
cargo checklike progress while being a wrapper aroundcargo check, so we'll need json messages to support all of the progress reporting needs
Reacted by Josh Junon, Marcin Konowalczyk and Eyal KalderonI'll have to see if the unit graph produces the same number of invocations but it at least gives similar information, thanks @epage, appreciate it :)
Would unit graph work?
i was meaning to try this for a while and "yes, but with more effort" seems to be the answer: https://github.com/lczyk/not-quite-cargo/tree/main/go. with, more of less,
osandarchyou can massage the unit graph into a decent-enough build plan without ever runningcargo buildbtw
I think we should work to improve our json messages. ...
note that build-time json messages are not an alternative for build-plan for all uses. notably, to get them you need to run the build itself while both build-plan and unit-graph work pre-build. not mourning build flags ;) , just underlining one perspective for the design of future stable plumbing.
Reacted by Josh Junon
View all comments
Proposal to close: #7614 (comment)
The cargo team has been talking about this for some time now, and this is an issue I'd like to open to cc others and get some discussion about this.
The build-plan feature of Cargo is broken, and has always been broken. It has never actually accounted for all the build intricacies of crate graphs that Cargo supports. It was landed to unblock initial work with the understanding that it wouldn't be stabilized before it was fleshed out more, but the work to flesh it out more hasn't happened since then. The build plan does not support, for example:
There is not a known great solution for these fundamental issues, and there has not been much effort to investigate this. Cargo has received very little maintenance of build plans and new features in Cargo typically don't consider keeping build plans working, leading to issues like #7604. Additionally build plans are only very lightly tested, so there's not a huge amount of protection against regressions.
Given all this the Cargo team is leaning towards deleting this feature. The existence of the feature seems to give the guise that it's supported and officially recommended, when in fact it's neither supported nor recommended. The feature, as implemented, seems dead in the water without significant refactorings that may require starting from scratch anyway.
The feature, however, currently has what we believe is enough users that we don't want to just outright delete it. We'd like to cc some folks who we believe are using this feature on this issue. If you're not using the feature or you're not interested, sorry for the cc but feel free to unsubscribe yourself!
The Cargo team is specifically interested in asking others if they are aware of the downsides of the build plan feature, and also if others are available to help fix this feature and implement a working system. The Cargo team does not have the bandwidth to either design a working build plan or implement it at this time, so both the design and implementation work is what we're interested in getting help for.
While it's useful to list out the bugs in the current build plan, the Cargo team is hesitant to land fixes such as #7604 at this time. These "small fixes" perpetrate the sub-par integration of build plans into Cargo today and makes the codebase harder to maintain. What we're particularly interested is figuring out a way to get build plans onto more solid footing such that they can actually be supported.
cc @edwin0cheng
cc @vlad20012
cc @matklad
cc @Manishearth