-
Notifications
You must be signed in to change notification settings - Fork 72
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
Leverage Cargo #1138
base: main
Are you sure you want to change the base?
Leverage Cargo #1138
Conversation
3bb30c5
to
acbd12f
Compare
First off, high-level, this is awesome! I've been meaning to implement (or even write down my thoughts on how one might implement) I haven't had a chance to dive into the code yet (earliest I can get to a proper read might take quite some time; so I'll let others comment on it, esp wrt specifics), but I just wanted to write down my high-level thoughts as I read the proposal.
Overall, I support the addition of |
acbd12f
to
2613c1b
Compare
To prepare for including vstd in the workspace. Once it is included in the workspace, it will be visited by cargo fmt. We guard the rustfmt::skip attributes with: '#![cfg_attr(rustfmt, rustfmt::skip)]' because custom inner attributes are unstable.
Just to aid discussion and review.
2613c1b
to
c96e3fd
Compare
Thank you for this feedback!
When you posted your comment, I just modified
Great point! I've modified
To me, this seems like a perfect use-case for As for ensuring that
Yes, I think this is important. I just added such a check in 58f6561. |
Hi @nspin! Thank you for working on this and for the PR. I'm self-assigning as a reviewer because I've been responsible for the build process, and I'd like to take an in-depth look at this, and thank you @jaybosamiya for the preliminary review, your input is very much appreciated. It may also take me a little bit to properly get to this, but I'll try and prioritize it as much as I can because we'd definitely want (something like) this (and as @jaybosamiya said, we've wanted it for a while now), and I really appreciate the effort you put into this. |
What's the difference between From the illustrate.sh script, it looks to me like both of them do 'verification without codegen'. |
To
|
Jumping in to say this is super cool. Thanks for the contribution! |
Thank you so much for this PR! My current filesystem verification project does hugely benefit from cargo integration, as it makes use of external crates. Looking forward to its merge! |
This trick makes uses of a mechanism designed for building the Rust sysroot to ensure that the output of verus-driver via cargo-verus is distinguished from the output of rustc. The value of the __CARGO_DEFAULT_LIB_METADATA is incorporated into the hashes that are included in compilation output filenames.
Can you explain a bit more about how this integration handles dependencies? When Verus runs on a crate, it can export the specifications in a
So just to check my understanding: a dependency crate needs to emit the |
For until a proper one is added.
For until a proper one is added.
Using the package.metadata.verus tables of dependencies.
Using the 'anyhow' crate.
Using 'rustc_session::EarlyDiagCtxt'.
963d9d5
to
c1d8b98
Compare
Yes, this is correct.
Cargo (via the All of
If a rustc or
The answers below may sound like hacks, but they ultimately feel fine to me. I'd be curious to hear your takes on them. The intention behind them is for For packages with Until the change I just force pushed, this is how imports worked: For each package with I've just pushed a commit which changes the behavior to this: For each package with
Yes, |
Thanks for the detailed explanation. I finally got around to checking out the PR and actually playing around in the cargo-verus-illustration directory to get a sense for how it all works. To explain a bit how I'm thinking about this: I foresee that when running Verus in a multi-crate project, 99% of the time I'll want to do one of the following 3 things:
In short, it seems cargo-verus works solidly for (2) and (3) but much less so (1), which is probably the most common thing I want to do during active development. Here are some issues:
My biggest (technical) question is: How much control do we have over cargo's decision to re-run on all dependencies when command line arguments are added or removed? Is this a decision cargo makes automatically, or do we have freedom to determine which options are considered "inputs" that should trigger a re-verify when changed? |
(Sorry for the wait -- I was busy with an event last week -- I'm going to start looking at this in detail now, hope to get through it |
A few high level questions to start:
2 may be an acceptable substitute for 1 assuming the results of 2 for dependent crates have been cached and don't need recompilation and re-verification. @tjhance does that make sense, or do you see specific value in running verification for just that one specific crate. (I'm asking because the way @nspin is describing current Regarding @tjhance's issues:
I agree these are very important. Perhaps we can add a subcommand that allows for direct invocation of @nspin would you be up for hopping on a call later this week to discuss the design, and see if I can help with some of this? Thanks again. I'm also starting to look at the code. I think we may be able to simplify a couple things a little bit now that we have binary releases: https://github.com/verus-lang/verus/releases |
I do think it's important, though it certainly doesn't need to be addressed immediately in this PR. Right now, I'm mostly trying to figure out what our technical options are, hence my earlier questions about how cargo handles the command line flags (which I am still wondering about). The reason I think it's important is just a matter of our experience developing massive projects, which rarely proceeds in strict dependency order. It's not uncommon for large swathes of code to fail verification, but we don't want those issues to block work on other components. |
Sorry to disturb, but what's the current progress of this PR? Is there anything other than the cache issue that prevents it from being merged? |
Hi @panda2134, thanks for bringing this up. There is some duplication with existing build tooling that I'd like to resolve before merging, so that we avoid having multiple ways to set up a tool chain that may get out of sync. I hope to get to it |
Andrea and I talked about this and essentially this PR has not been forgotten, but it does need some further work to make the feature maintainable. |
This PR proposes integration with Cargo.
The primary changes in this PR are the addition of a custom Cargo subcommand called
cargo-verus
and a new CLI forrust_verify
calledverus-driver
. These additions leverage Cargo to make using Verus just as easy and ergonomic as using rustc itself from a tooling perspective. This PR could also simplify the build system of the Verus project itself.An invocation of
cargo verus
wraps Cargo to process a few Verus-specific flags, and then invokecargo build
orcargo check
withRUSTC_WRAPPER
set to another new binary calledverus-driver
. For the sake of modularity, I've split the CLI logic out ofrust_verify
and intoverus-driver
, which also handles all of the new Cargo integration logic. This addition required very little modification ofrust_verify
, but, at least in the first draft of this PR, there is now some redundancy betweenverus-driver
andrust_verify
, as the CLI inrust_verify
has been left unchanged. Note thatverus-driver
is designed to also be useful as a rustc driver when used directly, without Cargo.For each crate in the
cargo build
orcargo check
build plan,cargo-verus
uses package metadata tables to determine whether it should be compiled normally by rustc or treated specially by Verus, and informsverus-driver
via environment variables.The result of all of this is a much simpler and more familiar flow for Verus users. The ./source/cargo-verus-illustration/illustrate.sh script in this draft demonstrates such a flow. Note that this script can be run in a fresh checkout of the Verus repository. That is, it does not depend on Vargo or any other current Verus project build system code infrastructure. It does, however, require
$VERUS_Z3_PATH
and$VERUS_SINGULAR_PATH
to be set.The design implemented in this PR supports two ways of depending on
builtin
/builtin_macros
/vstd
. They can be included as normal Cargo project dependencies, or pre-built and bundled into a "Verus sysroot".illustrate.sh
demonstrates both.It seems to me that this integration with Cargo could replace some or even much of the functionality in the custom scripts in this repository (
vargo
,vstd_build
, andverus
).Note that, in this draft, the proposed new tooling does not yet include all features of the
verus
andrust_verify
tools. In particular, history recording and stat reporting have not been implemented.The design and implementation of this integration was guided that of by Clippy.
I recognize that this PR entails quite a significant proposal for a first-time contributor, so here is some context: I work on Rust support in userspace for seL4, the formally verified microkernel. As folks building high-assurance systems on top of seL4 have been increasingly reaching for Rust, they are looking to tools like Verus. I hope that with this PR, and beyond, I am able to facilitate that adoption.