-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should build-plans be deleted? #7614
Comments
FWIW, IntelliJ IDEA and rust-analyzer are only (atm) using build-plan to get the value of |
I'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 ( (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:
|
The core problem is that IntelliJ Rust needs a way to get It would be great to have some replacement feature for sniffing Ideally, this info should be a part of 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 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 EDIT: PR to add OUT_DIR to |
Note 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? |
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 ( |
Yes, that's currently how our support for external build systems work. We parse the 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 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. |
cc @jsgf |
I 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. |
Ok 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. |
I've used build plans to reduce compile times*. *: I was implementing code reloading for a game, and had noticed that running the final |
I've been planning (heh) on adding Cargo integration to Meson using the build-plan feature, so I was surprised and disappointed to hear that no one else has been working on it or using it actively. However, I'm glad to hear that the Cargo team wants something like build-plans to exist, since if I do find time to work on Cargo integration in Meson in the future, I would like to pick this up again. Thanks for the clear communication around this deprecation. |
@alexcrichton would you recommend me to investigate and propose build-plans v2 and estimated steps how the Cargo internals can be "rebased" on top of a build plan? If that's something Cargo Team is still interested in, I'd like to give it a shot. |
@denzp we're still very interesting in having something done in this space, but unfortunately the cargo team doesn't have a lot of time to help out with it right now. We'd like to see iteration and development on build plans, though, so it's trying to find a good balance of getting this feature designed/implemented with not halting other work to focus all efforts on this. That's unfortunately not a great answer, but if you're ok being pretty independent in investigating a "v2 build plans" that'd be best! |
Disclaimer: I haven't followed the whole conversation here, and I'm not even a cargo/rust user. But as a Meson and GStreamer developer (not maintainer) I tried to have a plan to integrate with Cargo. The big challenge is how do we pass dependency information from Meson to Cargo and vice-versa. I came to the conclusion that pkg-config's The missing part is doing the other way around: Use libraries built by Cargo in Meson. For that we would need Cargo to be able to generate -uninstalled.pc files at configure time (that concept does not yet exist in Cargo, AFAIK). So I think adding in cargo a mode that would:
That way, Meson could invoke that Cargo configuration step, then set PKG_CONFIG_PATH to the location of -uninstalled.pc files, so future I'm sure there still would be rough edges, but that would be a good start. |
This is something we're actively interested in prototyping as a part of the Firefox build. We've had a version of the Firefox build driven by the build plan in the past, and plans for this quarter to prototype that as a part of the default build. Our motivation for this is the idea that a full view of the cargo build graph will help parallelize and schedule rust compilation within our build more efficiently. We've made some measurements in the past that suggest scheduling and parallelizing rust is a significant bottleneck for Firefox builds, and this seems like a promising way forward. The shortcomings of the current build plan are significant, and impact our build -- hacking around some of the limitations mentioned here when I got this going last certainly didn't seem sustainable. However, prototyping things may prove gains sufficient to motivate investment in a future solution in this area. None of this directly bears on plans to delete the current build plan implementation necessarily, as I believe we can do this prototyping work within the time constraint of versions of cargo that continue to support build plans, but we wanted to add this to the discussion in the meantime. |
@chmanchester We've been finding that by building Rust with Buck gets a lot more global parallelism, esp because it has a global dependency graph that includes all languages and transformations (codegen, etc). Also it has a more effective global caching strategy. I've been having reasonably good success in semi-automatically deriving Buck build rules from Cargo; it certainly highlights the part of Cargo's design which are not well suited to deriving a global dep graph (primarily build scripts). But I think it's a promisiing approach for Cargo <-> Other integration that I'd like to continue to explore. But Cargo build plans as they currently stand don't help at all. |
@jsgf, that's good to know -- I'd be very interested in learning more about your approach if you have a link to this tool. |
The feature was initial attempt to support `include` macro with `OUT_DIR` variable. It has two major issues: - invocation of Cargo with `--build-plan` option force Cargo to recompile everything from the scratch next time - the option is supposed to be [removed](rust-lang/cargo#7614). Also, there is more powerful feature - `org.rust.cargo.evaluate.build.scripts` that allows plugin to know about all generated `cfg` options and environment variables (including `OUT_DIR`). So I think we can drop `--build-plan` support since it has major cons and can be superseded by `org.rust.cargo.evaluate.build.scripts` feature
The feature was an initial attempt to support `include` macro with `OUT_DIR` variable. It has two major issues: - invocation of Cargo with `--build-plan` option forces Cargo to recompile everything from the scratch next time - the option is supposed to be [removed](rust-lang/cargo#7614). Also, there is a more powerful feature - `org.rust.cargo.evaluate.build.scripts` that allows plugin to know about all generated `cfg` options and environment variables (including `OUT_DIR`). So I think we can drop `--build-plan` support since it has major cons and can be superseded by `org.rust.cargo.evaluate.build.scripts` feature
7142: CARGO: drop `org.rust.cargo.fetch.out.dir` feature r=vlad20012 a=Undin The feature was an initial attempt to support `include` macro with `OUT_DIR` variable. It has two major issues: - invocation of Cargo with `--build-plan` option forces Cargo to recompile everything from the scratch next time - the option is supposed to be [removed](rust-lang/cargo#7614). Also, there is a more powerful feature - `org.rust.cargo.evaluate.build.scripts` that allows plugin to know about all generated `cfg` options and environment variables (including `OUT_DIR`). So I think we can drop `--build-plan` support since it has major cons and can be superseded by `org.rust.cargo.evaluate.build.scripts` feature changelog: Drop support of `org.rust.cargo.evaluate.build.scripts` experimental feature. Use `org.rust.cargo.evaluate.build.scripts` instead if you need to evaluate `env!("OUT_DIR")` in your `include!` macro calls Co-authored-by: Arseniy Pendryak <[email protected]>
The feature was an initial attempt to support `include` macro with `OUT_DIR` variable. It has two major issues: - invocation of Cargo with `--build-plan` option forces Cargo to recompile everything from the scratch next time - the option is supposed to be [removed](rust-lang/cargo#7614). Also, there is a more powerful feature - `org.rust.cargo.evaluate.build.scripts` that allows plugin to know about all generated `cfg` options and environment variables (including `OUT_DIR`). So I think we can drop `--build-plan` support since it has major cons and can be superseded by `org.rust.cargo.evaluate.build.scripts` feature
Out of curiosity, what exactly is the status of this? |
The holy grail for production users is fine-grained caching of dependencies with reproducible builds. I have been trying to find some solutions in this space for a while - I spent the last couple of weeks exploring alternative The only way to have a robust integration point for other build systems would be to ensure that It would be great to understand, as an outsider, what is the "current" attempt at improving support for alternative build systems - I'd be more than happy to contribute, but at the moment I can't wrap my head around where this sits in terms of priority for the |
@LukeMathWalker We're using reindeer in production with good success. It uses I initially tried using build plans but they're just at the wrong level. I don't want a trace of what cargo would do, but a more declarative description of what needs to be done not how to do it. The main blocker here are build scripts since they can do unconstrained things with undescribed dependencies. |
We use a very similar approach for gn: |
I do have a use case in mind that I was hoping could be accommodated before removing build-plans. We have extended Rustc to generate other kinds of artifacts and we use the same name schema as Rustc, which includes the metadata suffix. AFAIK, build-plans is the only way we can reliably figure out the name of the files that we generate, especially when cargo build finds that everything is fresh. In that case, our compiler doesn't get invoked, and there is no easy way for us to tell which artifacts we should be using. We tried to extract the artifact name from the artifact messages, but for things like binaries, static / shared libraries, the list of filenames do not include the original files that were generated by the compiler. E.g.: For a static library, this is what I get: "filenames":["/tmp/test/static_lib/target/debug/libstatic_lib.a"] while for a rust library, I get: "filenames":["/tmp/test/libA/target/debug/liblibA.rlib","/tmp/test/libA/target/debug/deps/liblibA-728fd0386e8e49d7.rmeta"] On the other hand, "outputs": ["/tmp/test/static_lib/target/debug/deps/libstatic_lib-edb6526891c85cb2.a" ], |
One use-case where the current build-plan seems fit is when integrating Rust into an existing build system (the original intention), and having cargo actually build third-party crates (in contrast to using cargo just for version resolution as in e.g. reindeer and cargo-gnaw). The main motivation for this approach would be to avoid custom/manual parsing of build scripts: instead rustflags are automatically applied by cargo, generated Rust code is compiled in, and native code built with cc is bundled in the generated rlibs. Integration with the existing build system would then require knowledge of what output files will be produced by cargo ( Would it be reasonable to keep |
AFAIK the build plan only says how to build the build script and when to execute it. It doesn't contain the parsed output of the build script as that required building and executing the build script first, which is delegated to the consumer of the build plan. |
I agree, and if cargo is used to also build the third-party crates I think that is fine: as long as the output paths stay the same regardless of build script execution the external build system could ignore build scripts as cargo handles them appropriately during the build. |
@bbjornse sounds like you are wanting build metadata. This is less the purpose of build plans and I wonder if another feature would be more appropriate, like unit graph. I have proposed a project goal for new cargo plumbing commands which would include something like the unit graph. It is in need of someone to drive the effort. |
Thanks @epage, that might be - I'll take a closer look at the documents you referenced. Just to make clear what I had in mind, for external build system interop:
FWICT, the
Do you think unit graph or plumbing commands would be a better fit? Maybe e.g. a plumbing command which prints the set of compile-time and link-time dependencies for a given package could solve the problem even more directly? |
Ok, I missed the distinction that you are wanting to mix custom build with cargo build. That is a bit unusual. My hope for the unit graph is that everything cargo needs to perform a build, including unit dependencies and information about proc macros, will be included. It won't include information to the level of detail of how to run the commands. This would allow you to get at least most of that information (maybe we can include expected output, we do track it) and you could pass a subset of the unit graph to the proposed build plumbing command to build third-party crates. |
Sounds like unit graph is similar to the bear project but for rust. https://github.com/rizsotto/Bear/wiki For things like static analysis tools which require access to the raw invocations for instrumentation, this sounds like this is on the right path |
One difference between bear and unit-graph is that unit-graph gives the information up-front without requiring a full build. If running a build is okay, it's possible to use |
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
The text was updated successfully, but these errors were encountered: