|
| 1 | +# RMC on a package |
| 2 | + |
| 3 | +> RMC currently ships with a `cargo-rmc` script, but this support is deeply limited (e.g. to a single crate). |
| 4 | +> This will be corrected soon, and this documentation updated. |
| 5 | +> In the meantime, we document the current build process for a larger project with dependencies here. |
| 6 | +
|
| 7 | +To build a larger project (one with dependencies or multiple crates) with RMC, you currently need to: |
| 8 | + |
| 9 | +1. Build the project with an appropriate set of flags to output CBMC "symbol table" `.json` files. |
| 10 | +2. Link these together into a single "goto binary", with appropriate preprocessing flags. |
| 11 | +3. Directly call CBMC on this resulting binary. |
| 12 | + |
| 13 | +We give an example of this kind of script, with explanations, below. |
| 14 | + |
| 15 | +# Building and running |
| 16 | + |
| 17 | +Let's assume you have a project you can build with `cargo build` and you've written a proof harness somewhere in it that you want to run RMC on: |
| 18 | + |
| 19 | +```rust |
| 20 | +#[no_mangle] |
| 21 | +#[cfg(rmc)] |
| 22 | +fn my_harness() { |
| 23 | +} |
| 24 | +``` |
| 25 | + |
| 26 | +A sample build script might start like this: |
| 27 | + |
| 28 | +```bash |
| 29 | +{{#include sample-rmc-build.sh:cargo}} |
| 30 | +``` |
| 31 | + |
| 32 | +This allows us to re-use the `cargo` build system, but with flags that override `rustc` with RMC instead. |
| 33 | +More specifically, by setting the `RUSTC` environment variable to `rmc-rustc`, each Rust source file targeted by `cargo build` is "compiled" with RMC instead of `rustc`. |
| 34 | +The result of running `rmc-rustc` on a source file is a symbol table json file written in the CBMC Goto-C language. |
| 35 | +The use of an alternate target directory ensures RMC and rustc don't confuse each other with different intermediate output. |
| 36 | + |
| 37 | +Next we can convert the symbol tables into goto binaries, in parallel, and then link them together: |
| 38 | + |
| 39 | +```bash |
| 40 | +{{#include sample-rmc-build.sh:linking}} |
| 41 | +``` |
| 42 | + |
| 43 | +At this point we have the project built, but now we want to transform it into something that will run a specific proof harness. |
| 44 | +To do that, we specialize it, preprocess it, and then run CBMC on the result: |
| 45 | +(In practice, we might want to do the above steps once, then repeat the below steps for each proof harness.) |
| 46 | + |
| 47 | +```bash |
| 48 | +{{#include sample-rmc-build.sh:cbmc}} |
| 49 | +``` |
| 50 | + |
| 51 | +At this point we have a complete script and should now be able to run `./sample-rmc-build my_harness` to run a particular proof harness. |
| 52 | +Even in very large projects the removal of unreachable code should mean only the parts relevant to that proof harness are preserved in the RMC run. |
0 commit comments