Skip to content

Commit 035225c

Browse files
Enable build cache in cargo kani (#2232)
This change re-enable the build cache in Kani. For that, we also added a new dummy option that includes Kani's version, which will ensure that the cache gets refreshed when the user upgrades Kani. We also enabled an option to force rebuild: `--force-build` Co-authored-by: Zyad Hassan <[email protected]>
1 parent 9ad7eeb commit 035225c

File tree

22 files changed

+388
-10
lines changed

22 files changed

+388
-10
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,5 @@ exclude = [
6666
"tests/cargo-ui",
6767
"tests/slow",
6868
"tests/assess-scan-test-scaffold",
69+
"tests/script-based-pre",
6970
]

kani-compiler/src/codegen_cprover_gotoc/compiler_interface.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ impl CodegenBackend for GotocCodegenBackend {
8181
provide::provide_extern(providers);
8282
}
8383

84+
fn print_version(&self) {
85+
println!("Kani-goto version: {}", env!("CARGO_PKG_VERSION"));
86+
}
87+
8488
fn codegen_crate(
8589
&self,
8690
tcx: TyCtxt,

kani-compiler/src/parser.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,6 @@ pub const ENABLE_STUBBING: &str = "enable-stubbing";
4646
/// Configure command options for the Kani compiler.
4747
pub fn parser() -> Command {
4848
let app = command!()
49-
.arg(
50-
Arg::new("kani-compiler-version")
51-
.short('?')
52-
.action(ArgAction::Version)
53-
.help("Gets `kani-compiler` version."),
54-
)
5549
.arg(
5650
Arg::new(KANI_LIB)
5751
.long(KANI_LIB)
@@ -137,6 +131,12 @@ pub fn parser() -> Command {
137131
.help("Instruct the compiler to perform stubbing.")
138132
.requires(HARNESS)
139133
.action(ArgAction::SetTrue),
134+
)
135+
.arg(
136+
Arg::new("check-version")
137+
.long("check-version")
138+
.action(ArgAction::Set)
139+
.help("Pass the kani version to the compiler to ensure cache coherence."),
140140
);
141141
#[cfg(feature = "unsound_experiments")]
142142
let app = crate::unsound_experiments::arg_parser::add_unsound_experiments_to_parser(app);

kani-driver/src/args.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ pub struct KaniArgs {
113113
#[arg(long)]
114114
pub target_dir: Option<PathBuf>,
115115

116+
/// Force Kani to rebuild all packages before the verification.
117+
#[arg(long)]
118+
pub force_build: bool,
119+
116120
/// Toggle between different styles of output
117121
#[arg(long, default_value = "regular", ignore_case = true, value_enum)]
118122
pub output_format: OutputFormat,

kani-driver/src/call_cargo.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ impl KaniSession {
5151
.join("kani");
5252
let outdir = target_dir.join(build_target).join("debug/deps");
5353

54-
// Clean directory before building since we are unable to handle cache today.
55-
// TODO: https://github.com/model-checking/kani/issues/1736
56-
if target_dir.exists() {
54+
if self.args.force_build && target_dir.exists() {
5755
fs::remove_dir_all(&target_dir)?;
5856
}
5957

kani-driver/src/call_single_file.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl KaniSession {
6666

6767
/// These arguments are arguments passed to kani-compiler that are `kani` compiler specific.
6868
pub fn kani_compiler_flags(&self) -> Vec<String> {
69-
let mut flags = vec![];
69+
let mut flags = vec![check_version()];
7070

7171
if self.args.debug {
7272
flags.push("--log-level=debug".into());
@@ -187,3 +187,11 @@ impl KaniSession {
187187
pub fn to_rustc_arg(kani_args: Vec<String>) -> String {
188188
format!(r#"-Cllvm-args={}"#, kani_args.join(" "))
189189
}
190+
191+
/// Function that returns a `--check-version` argument to be added to the compiler flags.
192+
/// This is really just used to force the compiler to recompile everything from scratch when a user
193+
/// upgrades Kani. Cargo currently ignores the codegen backend version.
194+
/// See <https://github.com/model-checking/kani/issues/2140> for more context.
195+
fn check_version() -> String {
196+
format!("--check-version={}", env!("CARGO_PKG_VERSION"))
197+
}

tests/cargo-ui/supported-lib-types/lib-rlib/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,16 @@ description = "Test that Kani correctly handle supported crate types"
1010
name = "lib"
1111
crate-type = ["lib", "rlib"]
1212
path = "../src/lib.rs"
13+
14+
[package.metadata.kani.flags]
15+
# This test doesn't work with the cache due to naming conflict caused by
16+
# declaring ["lib", "rlib"] which is in fact redundant.
17+
# See https://github.com/rust-lang/cargo/issues/6313 for more details.
18+
#
19+
# This still works for a fresh build and it only prints a warning. Thus, we
20+
# force rebuild for now.
21+
#
22+
# Note that support for this case is deprecated. AFAIK, there is no plan to fix
23+
# cargo build cache for cases like this. Until then, we might as well check that
24+
# our support level matches cargo's.
25+
force-build = true
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright Kani Contributors
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
[package]
4+
name = "bin"
5+
version = "0.1.0"
6+
edition = "2021"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
#[kani::proof]
4+
fn cover_bool() {
5+
match kani::any() {
6+
true => kani::cover!(true, "true"),
7+
false => kani::cover!(true, "false"),
8+
}
9+
}
10+
11+
#[kani::proof]
12+
fn cover_option() {
13+
match kani::any() {
14+
Some(true) => kani::cover!(true, "true"),
15+
Some(false) => kani::cover!(true, "false"),
16+
None => kani::cover!(true, "none"),
17+
}
18+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Initial compilation
2+
target/initial.log:Compiled 1 crates
3+
target/initial.log:No harness verified
4+
Re-execute the same command
5+
target/same.log:Compiled 0 crates
6+
target/same.log:No harness verified
7+
Run with new arg that affects kani-driver workflow only
8+
target/driver_opt.log:Compiled 0 crates
9+
target/driver_opt.log:Checking harness cover_option...
10+
target/driver_opt.log:Checking harness cover_bool...
11+
target/driver_opt.log:Complete - 2 successfully verified harnesses, 0 failures, 2 total.
12+
Run with a new argument that affects compilation
13+
target/disable_checks.log:Compiled 1 crates
14+
target/disable_checks.log:Checking harness cover_option...
15+
target/disable_checks.log:Checking harness cover_bool...
16+
target/disable_checks.log:Complete - 2 successfully verified harnesses, 0 failures, 2 total.
17+
Run with new dependency
18+
target/new_dep.log:Compiled 2 crates
19+
target/new_dep.log:Checking harness cover_option...
20+
target/new_dep.log:Checking harness cover_bool...
21+
target/new_dep.log:Complete - 2 successfully verified harnesses, 0 failures, 2 total.

0 commit comments

Comments
 (0)