-
Notifications
You must be signed in to change notification settings - Fork 129
Enable build cache in cargo kani
#2232
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
Changes from all commits
5ef456a
23d526c
157bd0e
0b41b5b
d78e27d
764f83f
480ead6
980b950
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,4 +66,5 @@ exclude = [ | |
| "tests/cargo-ui", | ||
| "tests/slow", | ||
| "tests/assess-scan-test-scaffold", | ||
| "tests/script-based-pre", | ||
| ] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,12 +46,6 @@ pub const ENABLE_STUBBING: &str = "enable-stubbing"; | |
| /// Configure command options for the Kani compiler. | ||
| pub fn parser() -> Command { | ||
| let app = command!() | ||
| .arg( | ||
| Arg::new("kani-compiler-version") | ||
| .short('?') | ||
| .action(ArgAction::Version) | ||
| .help("Gets `kani-compiler` version."), | ||
| ) | ||
| .arg( | ||
| Arg::new(KANI_LIB) | ||
| .long(KANI_LIB) | ||
|
|
@@ -137,6 +131,12 @@ pub fn parser() -> Command { | |
| .help("Instruct the compiler to perform stubbing.") | ||
| .requires(HARNESS) | ||
| .action(ArgAction::SetTrue), | ||
| ) | ||
| .arg( | ||
| Arg::new("check-version") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: should this be called
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just a dummy argument, so I don't think it matters. I figured that we could eventually ensure that the kani-compiler matches the driver version, but I didn't bother here. |
||
| .long("check-version") | ||
| .action(ArgAction::Set) | ||
| .help("Pass the kani version to the compiler to ensure cache coherence."), | ||
| ); | ||
| #[cfg(feature = "unsound_experiments")] | ||
| let app = crate::unsound_experiments::arg_parser::add_unsound_experiments_to_parser(app); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # Copyright Kani Contributors | ||
| # SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| [package] | ||
| name = "bin" | ||
| version = "0.1.0" | ||
| edition = "2021" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // Copyright Kani Contributors | ||
| // SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| #[kani::proof] | ||
| fn cover_bool() { | ||
| match kani::any() { | ||
| true => kani::cover!(true, "true"), | ||
| false => kani::cover!(true, "false"), | ||
| } | ||
| } | ||
|
|
||
| #[kani::proof] | ||
| fn cover_option() { | ||
| match kani::any() { | ||
| Some(true) => kani::cover!(true, "true"), | ||
| Some(false) => kani::cover!(true, "false"), | ||
| None => kani::cover!(true, "none"), | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| Initial compilation | ||
| target/initial.log:Compiled 1 crates | ||
| target/initial.log:No harness verified | ||
| Re-execute the same command | ||
| target/same.log:Compiled 0 crates | ||
| target/same.log:No harness verified | ||
| Run with new arg that affects kani-driver workflow only | ||
| target/driver_opt.log:Compiled 0 crates | ||
| target/driver_opt.log:Checking harness cover_option... | ||
| target/driver_opt.log:Checking harness cover_bool... | ||
| target/driver_opt.log:Complete - 2 successfully verified harnesses, 0 failures, 2 total. | ||
| Run with a new argument that affects compilation | ||
| target/disable_checks.log:Compiled 1 crates | ||
| target/disable_checks.log:Checking harness cover_option... | ||
| target/disable_checks.log:Checking harness cover_bool... | ||
| target/disable_checks.log:Complete - 2 successfully verified harnesses, 0 failures, 2 total. | ||
| Run with new dependency | ||
| target/new_dep.log:Compiled 2 crates | ||
| target/new_dep.log:Checking harness cover_option... | ||
| target/new_dep.log:Checking harness cover_bool... | ||
| target/new_dep.log:Complete - 2 successfully verified harnesses, 0 failures, 2 total. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| #!/usr/bin/env bash | ||
| # Copyright Kani Contributors | ||
| # SPDX-License-Identifier: Apache-2.0 OR MIT | ||
|
|
||
| # Checks situations where running kani multiple times will work as expected when | ||
| # the target crate is binary. | ||
| # | ||
| # The following checks should not trigger recompilation. | ||
| # - Exact same input being invoked a second time. | ||
| # - Different options that do not affect the compilation, only the Kani workt flow. | ||
| # While the following should recompile the target. | ||
| # - Pass a new argument that affects compilation | ||
| # - Add a dependency | ||
| set -e | ||
| set -u | ||
|
|
||
| ORIG=bin | ||
| OUT_DIR=target | ||
| MANIFEST=${OUT_DIR}/${ORIG}/Cargo.toml | ||
|
|
||
| # Expects two arguments: "kani arguments" "output_file" | ||
| function check_kani { | ||
| local args=$1 | ||
| local log_file="${OUT_DIR}/$2" | ||
| # Run kani with the given arguments | ||
| if [ -z "${args}" ] | ||
| then | ||
| cargo kani --manifest-path "${MANIFEST}" --target-dir "${OUT_DIR}" \ | ||
| 2>&1 | tee "${log_file}" | ||
| else | ||
| cargo kani --manifest-path "${MANIFEST}" --target-dir "${OUT_DIR}" \ | ||
| "${args}" 2>&1 | tee "${log_file}" | ||
| fi | ||
|
|
||
| # Print information about the generated log file. | ||
| # Check for occurrences of "Compiling" messages in the log files | ||
| local compiled=$(grep -c "Compiling" ${log_file}) | ||
| echo "${log_file}:Compiled ${compiled} crates" | ||
|
|
||
| # Check which harnesses were verified | ||
| grep "Checking harness" -H ${log_file} || echo "${log_file}:No harness verified" | ||
|
|
||
| # Check the verification summary | ||
| grep "successfully verified harnesses" -H ${log_file} || true | ||
| } | ||
|
|
||
| # Ensure output folder is clean | ||
| rm -rf ${OUT_DIR} | ||
| mkdir -p ${OUT_DIR} | ||
| # Move the original source to the output folder since it will be modified | ||
| cp -r ${ORIG} ${OUT_DIR} | ||
|
|
||
| echo "Initial compilation" | ||
| check_kani --only-codegen initial.log | ||
|
|
||
| echo "Re-execute the same command" | ||
| check_kani --only-codegen same.log | ||
|
|
||
| echo "Run with new arg that affects kani-driver workflow only" | ||
adpaco-aws marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| check_kani "" driver_opt.log | ||
|
|
||
| echo "Run with a new argument that affects compilation" | ||
| check_kani --no-assertion-reach-checks disable_checks.log | ||
|
|
||
| echo "Run with new dependency" | ||
| cargo new --lib ${OUT_DIR}/new_dep | ||
| cargo add new_dep --manifest-path ${MANIFEST} --path ${OUT_DIR}/new_dep | ||
| check_kani --no-assertion-reach-checks new_dep.log | ||
|
|
||
| # Try to leave a clean output folder at the end | ||
| rm -rf ${OUT_DIR} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Copyright Kani Contributors | ||
| # SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| script: cache_works.sh | ||
| expected: cache_works.expected |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Copyright Kani Contributors | ||
| # SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| script: rebuild.sh | ||
| expected: rebuild.expected |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| Initial compilation | ||
| omplete - 2 successfully verified harnesses, 0 failures, 2 total. | ||
| target/initial.log:Compiled 2 crates | ||
| target/initial.log:Checking harness check_u8_i16... | ||
| target/initial.log:Checking harness check_u8_u32... | ||
| target/initial.log:Complete - 2 successfully verified harnesses, 0 failures, 2 total. | ||
| Run with a new argument that affects compilation | ||
| target/enable_checks.log:Compiled 2 crates | ||
| target/enable_checks.log:Checking harness check_u8_i16... | ||
| target/enable_checks.log:Checking harness check_u8_u32... | ||
| target/enable_checks.log:Complete - 2 successfully verified harnesses, 0 failures, 2 total. | ||
| Run after change to the source code | ||
| target/changed_src.log:Compiled 1 crates | ||
| target/changed_src.log:Checking harness noop_check... | ||
| target/changed_src.log:Checking harness check_u8_i16... | ||
| target/changed_src.log:Checking harness check_u8_u32... | ||
| target/changed_src.log:Complete - 3 successfully verified harnesses, 0 failures, 3 total. | ||
| Run with new dependency | ||
| target/new_dep.log:Compiled 2 crates | ||
| target/new_dep.log:Checking harness noop_check... | ||
| target/new_dep.log:Checking harness check_u8_i16... | ||
| target/new_dep.log:Checking harness check_u8_u32... | ||
| target/new_dep.log:Complete - 3 successfully verified harnesses, 0 failures, 3 total. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| #!/usr/bin/env bash | ||
| # Copyright Kani Contributors | ||
| # SPDX-License-Identifier: Apache-2.0 OR MIT | ||
|
|
||
| # Checks situations where running kani multiple times should trigger a new build | ||
| # The cases we cover here are: | ||
| # - Pass a new argument that affects compilation | ||
| # - Change the source code | ||
| # - Add a dependency | ||
| # Note: This should run in the folder where the script is. | ||
|
|
||
| OUT_DIR=target | ||
| MANIFEST=${OUT_DIR}/target_lib/Cargo.toml | ||
| LIB_SRC=${OUT_DIR}/target_lib/src/lib.rs | ||
|
|
||
| # Expects two arguments: "kani arguments" "output_file" | ||
| function check_kani { | ||
| local args=$1 | ||
| local log_file="${OUT_DIR}/$2" | ||
| # Run kani with the given arguments | ||
| if [ -z "${args}" ] | ||
| then | ||
| cargo kani --manifest-path "${MANIFEST}" --target-dir "${OUT_DIR}" \ | ||
| 2>&1 | tee "${log_file}" | ||
| else | ||
| cargo kani --manifest-path "${MANIFEST}" --target-dir "${OUT_DIR}" \ | ||
| "${args}" 2>&1 | tee "${log_file}" | ||
| fi | ||
|
|
||
| # Print information about the generated log file. | ||
| # Check for occurrences of "Compiling" messages in the log files | ||
| local compiled=$(grep -c "Compiling" ${log_file}) | ||
| echo "${log_file}:Compiled ${compiled} crates" | ||
|
|
||
| # Check which harnesses were verified | ||
| grep "Checking harness" -H ${log_file} || echo "${log_file}:No harness verified" | ||
|
|
||
| # Check the verification summary | ||
| grep "successfully verified harnesses" -H ${log_file} || true | ||
| } | ||
|
|
||
| # Ensure output folder is clean | ||
| rm -rf ${OUT_DIR} | ||
| mkdir -p ${OUT_DIR} | ||
|
|
||
| # Copy the project so we don't make changes to the source code | ||
| cp -r target_lib ${OUT_DIR} | ||
|
|
||
| echo "Initial compilation" | ||
| check_kani --no-assertion-reach-checks initial.log | ||
|
|
||
| echo "Run with a new argument that affects compilation" | ||
| check_kani "" enable_checks.log | ||
|
|
||
| echo "Run after change to the source code" | ||
| echo ' | ||
| #[kani::proof] | ||
| fn noop_check() {} | ||
| ' >> ${LIB_SRC} | ||
| check_kani "" changed_src.log | ||
|
|
||
| echo "Run with new dependency" | ||
| cargo new --lib ${OUT_DIR}/new_dep | ||
| cargo add new_dep --manifest-path ${MANIFEST} --path ${OUT_DIR}/new_dep | ||
| check_kani "" new_dep.log | ||
|
|
||
| # Try to leave a clean output folder at the end | ||
| rm -rf ${OUT_DIR} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # Copyright Kani Contributors | ||
| # SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| [package] | ||
| name = "target_lib" | ||
| version = "0.1.0" | ||
| edition = "2021" | ||
|
|
||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
|
||
| [dependencies] | ||
| either = "1.8" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| // Copyright Kani Contributors | ||
| // SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| //! We don't use any of our dependencies to keep the test fast | ||
|
|
||
| #[kani::proof] | ||
| fn check_u8_u32() { | ||
| let before: u8 = kani::any(); | ||
| let temp = before as u32; | ||
| let after: u8 = temp.try_into().unwrap(); | ||
| assert_eq!(after, before); | ||
| } | ||
|
|
||
| #[kani::proof] | ||
| fn check_u8_i16() { | ||
| let before: u8 = kani::any(); | ||
| let temp = before as i16; | ||
| let after: u8 = temp.try_into().unwrap(); | ||
| assert_eq!(after, before); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| Initial compilation | ||
| target/initial.log:Compiled 1 crates | ||
| target/initial.log:No harness verified | ||
| Re-execute the same command | ||
| target/same.log:Compiled 0 crates | ||
| target/same.log:No harness verified | ||
| Run with new arg that affects kani-driver workflow only | ||
| target/driver_opt.log:Compiled 0 crates | ||
| target/driver_opt.log:Checking harness cover_option... | ||
| target/driver_opt.log:Checking harness cover_bool... | ||
| target/driver_opt.log:Complete - 2 successfully verified harnesses, 0 failures, 2 total. | ||
| Run with a new cbmc option | ||
| target/cbmc_opt.log:Compiled 0 crates | ||
| target/cbmc_opt.log:Checking harness cover_option... | ||
| target/cbmc_opt.log:Checking harness cover_bool... | ||
| target/cbmc_opt.log:Complete - 2 successfully verified harnesses, 0 failures, 2 total. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to be used anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In theory this is a function that the compiler uses to print the codegen version. Note that it is part of the implementation of the
CodegenBackendtrait.There is a limitation in the compiler today where this doesn't get invoked for codegen backend that was configured via the driver, but I figured we might as well implement it and once this issue gets fixed, we get our version printed correctly.