Skip to content

Commit ab56b9d

Browse files
celinvaljaisnan
andauthored
Add kani_core library placeholder and build logic (rust-lang#3227)
While at it, I also added a `--skip-libs` to skip rebuilding the Kani libraries and standard library at every `cargo build-dev` execution. We usually only need to rebuild the libraries when we make changes to them or when we update the Rust toolchain. Rebuilding them can be quite time consuming when you are making changes to Kani. Towards rust-lang#3226 rust-lang#3153 Co-authored-by: Jaisurya Nanduri <[email protected]>
1 parent 358ade9 commit ab56b9d

File tree

8 files changed

+79
-20
lines changed

8 files changed

+79
-20
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,13 @@ dependencies = [
468468
"os_info",
469469
]
470470

471+
[[package]]
472+
name = "kani_core"
473+
version = "0.51.0"
474+
dependencies = [
475+
"kani_macros",
476+
]
477+
471478
[[package]]
472479
name = "kani_macros"
473480
version = "0.52.0"

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ members = [
4343
"kani-driver",
4444
"kani-compiler",
4545
"kani_metadata",
46+
"library/kani_core",
4647
]
4748

4849
# This indicates what package to e.g. build with 'cargo build' without --workspace

library/kani_core/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright Kani Contributors
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
[package]
4+
name = "kani_core"
5+
version = "0.51.0"
6+
edition = "2021"
7+
license = "MIT OR Apache-2.0"
8+
publish = false
9+
10+
[dependencies]
11+
kani_macros = { path = "../kani_macros", features = ["no_core"] }

library/kani_core/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
//! This is placeholder for the new `kani_core` library.
5+
#![feature(no_core)]

library/kani_macros/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ syn = { version = "2.0.18", features = ["full", "visit-mut", "visit"] }
1919

2020
[package.metadata.rust-analyzer]
2121
# This package uses rustc crates.
22-
rustc_private=true
22+
rustc_private = true
23+
24+
[features]
25+
no_core = []

tools/build-kani/src/main.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@ fn main() -> Result<()> {
1919
let args = parser::ArgParser::parse();
2020

2121
match args.subcommand {
22-
parser::Commands::BuildDev(build_parser) => build_lib(&build_bin(&build_parser.args)?),
22+
parser::Commands::BuildDev(build_parser) => {
23+
let bin_folder = &build_bin(&build_parser.args)?;
24+
if !build_parser.skip_libs {
25+
build_lib(&bin_folder)?;
26+
}
27+
Ok(())
28+
}
2329
parser::Commands::Bundle(bundle_parser) => {
2430
let version_string = bundle_parser.version;
2531
let kani_string = format!("kani-{version_string}");

tools/build-kani/src/parser.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ pub struct BuildDevParser {
1717
/// Arguments to be passed down to cargo when building cargo binaries.
1818
#[clap(value_name = "ARG", allow_hyphen_values = true)]
1919
pub args: Vec<String>,
20+
/// Do not re-build Kani libraries. Only use this if you know there has been no changes to Kani
21+
/// libraries or the underlying Rust compiler.
22+
#[clap(long)]
23+
pub skip_libs: bool,
2024
}
2125

2226
#[derive(Args, Debug, Eq, PartialEq)]

tools/build-kani/src/sysroot.rs

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,29 @@ pub fn kani_playback_lib() -> PathBuf {
5555
path_buf!(kani_sysroot(), "playback/lib")
5656
}
5757

58+
/// Returns the path to where Kani libraries for no_core is kept.
59+
pub fn kani_no_core_lib() -> PathBuf {
60+
path_buf!(kani_sysroot(), "no_core/lib")
61+
}
62+
5863
/// Returns the path to where Kani's pre-compiled binaries are stored.
5964
fn kani_sysroot_bin() -> PathBuf {
6065
path_buf!(kani_sysroot(), "bin")
6166
}
6267

68+
/// Returns the build target
69+
fn build_target() -> &'static str {
70+
env!("TARGET")
71+
}
72+
6373
/// Build the `lib/` folder and `lib-playback/` for the new sysroot.
6474
/// - The `lib/` folder contains the sysroot for verification.
6575
/// - The `lib-playback/` folder contains the sysroot used for playback.
6676
pub fn build_lib(bin_folder: &Path) -> Result<()> {
6777
let compiler_path = bin_folder.join("kani-compiler");
6878
build_verification_lib(&compiler_path)?;
69-
build_playback_lib(&compiler_path)
79+
build_playback_lib(&compiler_path)?;
80+
build_no_core_lib(&compiler_path)
7081
}
7182

7283
/// Build the `lib/` folder for the new sysroot used during verification.
@@ -75,34 +86,40 @@ fn build_verification_lib(compiler_path: &Path) -> Result<()> {
7586
let extra_args =
7687
["-Z", "build-std=panic_abort,std,test", "--config", "profile.dev.panic=\"abort\""];
7788
let compiler_args = ["--kani-compiler", "-Cllvm-args=--ignore-global-asm --build-std"];
78-
build_kani_lib(compiler_path, &kani_sysroot_lib(), &extra_args, &compiler_args)
89+
let packages = ["std", "kani", "kani_macros"];
90+
let artifacts = build_kani_lib(compiler_path, &packages, &extra_args, &compiler_args)?;
91+
copy_artifacts(&artifacts, &kani_sysroot_lib(), true)
7992
}
8093

8194
/// Build the `lib-playback/` folder that will be used during counter example playback.
8295
/// This will include Kani's libraries compiled with `concrete-playback` feature enabled.
8396
fn build_playback_lib(compiler_path: &Path) -> Result<()> {
8497
let extra_args =
8598
["--features=std/concrete_playback,kani/concrete_playback", "-Z", "build-std=std,test"];
86-
build_kani_lib(compiler_path, &kani_playback_lib(), &extra_args, &[])
99+
let packages = ["std", "kani", "kani_macros"];
100+
let artifacts = build_kani_lib(compiler_path, &packages, &extra_args, &[])?;
101+
copy_artifacts(&artifacts, &kani_playback_lib(), true)
102+
}
103+
104+
/// Build the no core library folder that will be used during std verification.
105+
fn build_no_core_lib(compiler_path: &Path) -> Result<()> {
106+
let extra_args = ["--features=kani_macros/no_core"];
107+
let packages = ["kani_core", "kani_macros"];
108+
let artifacts = build_kani_lib(compiler_path, &packages, &extra_args, &[])?;
109+
copy_artifacts(&artifacts, &kani_no_core_lib(), false)
87110
}
88111

89112
fn build_kani_lib(
90113
compiler_path: &Path,
91-
output_path: &Path,
114+
packages: &[&str],
92115
extra_cargo_args: &[&str],
93116
extra_rustc_args: &[&str],
94-
) -> Result<()> {
117+
) -> Result<Vec<Artifact>> {
95118
// Run cargo build with -Z build-std
96-
let target = env!("TARGET");
119+
let target = build_target();
97120
let target_dir = env!("KANI_BUILD_LIBS");
98121
let args = [
99122
"build",
100-
"-p",
101-
"std",
102-
"-p",
103-
"kani",
104-
"-p",
105-
"kani_macros",
106123
"-Z",
107124
"unstable-options",
108125
"--target-dir",
@@ -137,6 +154,7 @@ fn build_kani_lib(
137154
.env("CARGO_ENCODED_RUSTFLAGS", rustc_args.join("\x1f"))
138155
.env("RUSTC", compiler_path)
139156
.args(args)
157+
.args(packages.iter().copied().flat_map(|pkg| ["-p", pkg]))
140158
.args(extra_cargo_args)
141159
.stdout(Stdio::piped())
142160
.spawn()
@@ -152,20 +170,24 @@ fn build_kani_lib(
152170
}
153171

154172
// Create sysroot folder hierarchy.
155-
copy_artifacts(&artifacts, output_path, target)
173+
Ok(artifacts)
156174
}
157175

158176
/// Copy all the artifacts to their correct place to generate a valid sysroot.
159-
fn copy_artifacts(artifacts: &[Artifact], sysroot_lib: &Path, target: &str) -> Result<()> {
160-
// Create sysroot folder hierarchy.
177+
fn copy_artifacts(artifacts: &[Artifact], sysroot_lib: &Path, copy_std: bool) -> Result<()> {
178+
// Create sysroot folder.
161179
sysroot_lib.exists().then(|| fs::remove_dir_all(sysroot_lib));
162-
let std_path = path_buf!(&sysroot_lib, "rustlib", target, "lib");
163-
fs::create_dir_all(&std_path).expect(&format!("Failed to create {std_path:?}"));
180+
fs::create_dir_all(sysroot_lib)?;
164181

165182
// Copy Kani libraries into sysroot top folder.
166183
copy_libs(&artifacts, &sysroot_lib, &is_kani_lib);
184+
167185
// Copy standard libraries into rustlib/<target>/lib/ folder.
168-
copy_libs(&artifacts, &std_path, &is_std_lib);
186+
if copy_std {
187+
let std_path = path_buf!(&sysroot_lib, "rustlib", build_target(), "lib");
188+
fs::create_dir_all(&std_path).expect(&format!("Failed to create {std_path:?}"));
189+
copy_libs(&artifacts, &std_path, &is_std_lib);
190+
}
169191
Ok(())
170192
}
171193

0 commit comments

Comments
 (0)