Skip to content

Commit ddd0cef

Browse files
authored
Merge pull request rust-lang#4506 from Patrick-6/miri-genmc-mvp
Add minimal functionality for using GenMC mode
2 parents f0c9c38 + c1be740 commit ddd0cef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+3667
-481
lines changed

src/tools/miri/Cargo.lock

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,9 @@ dependencies = [
363363

364364
[[package]]
365365
name = "cxx"
366-
version = "1.0.161"
366+
version = "1.0.173"
367367
source = "registry+https://github.com/rust-lang/crates.io-index"
368-
checksum = "a3523cc02ad831111491dd64b27ad999f1ae189986728e477604e61b81f828df"
368+
checksum = "6c64ed3da1c337cbaae7223cdcff8b4dddf698d188cd3eaddd1116f6b0295950"
369369
dependencies = [
370370
"cc",
371371
"cxxbridge-cmd",
@@ -377,9 +377,9 @@ dependencies = [
377377

378378
[[package]]
379379
name = "cxx-build"
380-
version = "1.0.161"
380+
version = "1.0.173"
381381
source = "registry+https://github.com/rust-lang/crates.io-index"
382-
checksum = "212b754247a6f07b10fa626628c157593f0abf640a3dd04cce2760eca970f909"
382+
checksum = "ae0a26a75a05551f5ae3d75b3557543d06682284eaa7419113162d602cb45766"
383383
dependencies = [
384384
"cc",
385385
"codespan-reporting",
@@ -392,9 +392,9 @@ dependencies = [
392392

393393
[[package]]
394394
name = "cxxbridge-cmd"
395-
version = "1.0.161"
395+
version = "1.0.173"
396396
source = "registry+https://github.com/rust-lang/crates.io-index"
397-
checksum = "f426a20413ec2e742520ba6837c9324b55ffac24ead47491a6e29f933c5b135a"
397+
checksum = "952d408b6002b7db4b36da07c682a9cbb34f2db0efa03e976ae50a388414e16c"
398398
dependencies = [
399399
"clap",
400400
"codespan-reporting",
@@ -406,15 +406,15 @@ dependencies = [
406406

407407
[[package]]
408408
name = "cxxbridge-flags"
409-
version = "1.0.161"
409+
version = "1.0.173"
410410
source = "registry+https://github.com/rust-lang/crates.io-index"
411-
checksum = "a258b6069020b4e5da6415df94a50ee4f586a6c38b037a180e940a43d06a070d"
411+
checksum = "ccbd201b471c75c6abb6321cace706d1982d270e308b891c11a3262d320f5265"
412412

413413
[[package]]
414414
name = "cxxbridge-macro"
415-
version = "1.0.161"
415+
version = "1.0.173"
416416
source = "registry+https://github.com/rust-lang/crates.io-index"
417-
checksum = "e8dec184b52be5008d6eaf7e62fc1802caf1ad1227d11b3b7df2c409c7ffc3f4"
417+
checksum = "2bea8b915bbc4cb4288f242aa7ca18b23ecc6965e4d6e7c1b07905e3fe2e0c41"
418418
dependencies = [
419419
"indexmap",
420420
"proc-macro2",
@@ -501,9 +501,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
501501

502502
[[package]]
503503
name = "foldhash"
504-
version = "0.1.5"
504+
version = "0.2.0"
505505
source = "registry+https://github.com/rust-lang/crates.io-index"
506-
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
506+
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
507507

508508
[[package]]
509509
name = "form_urlencoded"

src/tools/miri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ harness = false
7070

7171
[features]
7272
default = ["stack-cache", "native-lib"]
73-
genmc = ["dep:genmc-sys"] # this enables a GPL dependency!
73+
genmc = ["dep:genmc-sys"]
7474
stack-cache = []
7575
stack-cache-consistency-check = ["stack-cache"]
7676
tracing = ["serde_json"]

src/tools/miri/doc/genmc.md

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ Miri-GenMC integrates that model checker into Miri.
99

1010
## Usage
1111

12-
**IMPORTANT: The license of GenMC and thus the `genmc-sys` crate in the Miri repo is currently "GPL-3.0-or-later", so a binary produced with the `genmc` feature is subject to the requirements of the GPL. As long as that remains the case, the `genmc` feature of Miri is OFF-BY-DEFAULT and must be OFF for all Miri releases.**
13-
14-
For testing/developing Miri-GenMC (while keeping in mind the licensing issues):
12+
For testing/developing Miri-GenMC:
1513
- clone the Miri repo.
1614
- build Miri-GenMC with `./miri build --features=genmc`.
1715
- OR: install Miri-GenMC in the current system with `./miri install --features=genmc`
@@ -21,6 +19,21 @@ Basic usage:
2119
MIRIFLAGS="-Zmiri-genmc" cargo miri run
2220
```
2321

22+
Note that `cargo miri test` in GenMC mode is currently not supported.
23+
24+
### Supported Parameters
25+
26+
- `-Zmiri-genmc`: Enable GenMC mode (not required if any other GenMC options are used).
27+
- `-Zmiri-genmc-log=LOG_LEVEL`: Change the log level for GenMC. Default: `warning`.
28+
- `quiet`: Disable logging.
29+
- `error`: Print errors.
30+
- `warning`: Print errors and warnings.
31+
- `tip`: Print errors, warnings and tips.
32+
- If Miri is built with debug assertions, there are additional log levels available (downgraded to `tip` without debug assertions):
33+
- `debug1`: Print revisits considered by GenMC.
34+
- `debug2`: Print the execution graph after every memory access.
35+
- `debug3`: Print reads-from values considered by GenMC.
36+
2437
<!-- FIXME(genmc): explain options. -->
2538

2639
<!-- FIXME(genmc): explain Miri-GenMC specific functions. -->
@@ -57,6 +70,15 @@ The process for obtaining them is as follows:
5770
If you place this directory inside the Miri folder, it is recommended to call it `genmc-src` as that tells `./miri fmt` to avoid
5871
formatting the Rust files inside that folder.
5972

73+
### Formatting the C++ code
74+
75+
For formatting the C++ code we provide a `.clang-format` file in the `genmc-sys` directory.
76+
With `clang-format` installed, run this command to format the c++ files (replace the `-i` with `--dry-run` to just see the changes.):
77+
```
78+
find ./genmc-sys/cpp/ -name "*.cpp" -o -name "*.hpp" | xargs clang-format --style=file:"./genmc-sys/.clang-format" -i
79+
```
80+
NOTE: this is currently not done automatically on pull requests to Miri.
81+
6082
<!-- FIXME(genmc): explain how submitting code to GenMC should be handled. -->
6183

6284
<!-- FIXME(genmc): explain development. -->
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# .clang-format
2+
3+
BasedOnStyle: LLVM
4+
Standard: c++20
5+
6+
ColumnLimit: 100
7+
AllowShortFunctionsOnASingleLine: Empty
8+
AllowShortIfStatementsOnASingleLine: false
9+
AllowShortLoopsOnASingleLine: false
10+
AllowShortBlocksOnASingleLine: Empty
11+
BreakBeforeBraces: Attach
12+
13+
BinPackArguments: false
14+
BinPackParameters: false
15+
AllowAllParametersOfDeclarationOnNextLine: false
16+
AlwaysBreakAfterReturnType: None
17+
18+
# Force parameters to break and align
19+
AlignAfterOpenBracket: BlockIndent
20+
AllowAllArgumentsOnNextLine: false
21+
22+
# Spacing around braces and parentheses
23+
SpaceBeforeCtorInitializerColon: true
24+
SpaceBeforeInheritanceColon: true
25+
SpaceInEmptyBlock: false
26+
SpacesInContainerLiterals: true
27+
SpacesInParensOptions:
28+
InCStyleCasts: false
29+
InConditionalStatements: false
30+
InEmptyParentheses: false
31+
Other: false
32+
SpacesInSquareBrackets: false
33+
34+
# Brace spacing for initializers
35+
Cpp11BracedListStyle: false
36+
SpaceBeforeCpp11BracedList: true
37+
38+
# Import grouping: group standard, external, and project includes.
39+
IncludeBlocks: Regroup
40+
SortIncludes: true
41+
42+
# Granularity: sort includes per module/file.
43+
IncludeIsMainRegex: '([-_](test|unittest))?$'
44+
45+
# Miscellaneous
46+
SpaceAfterCStyleCast: true
47+
SpaceBeforeParens: ControlStatements
48+
PointerAlignment: Left
49+
IndentCaseLabels: true
50+
IndentWidth: 4
51+
TabWidth: 4
52+
UseTab: Never
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
[package]
22
authors = ["Miri Team"]
3-
# The parts in this repo are MIT OR Apache-2.0, but we are linking in
4-
# code from https://github.com/MPI-SWS/genmc which is GPL-3.0-or-later.
5-
license = "(MIT OR Apache-2.0) AND GPL-3.0-or-later"
3+
license = "MIT OR Apache-2.0"
64
name = "genmc-sys"
75
version = "0.1.0"
86
edition = "2024"
97

108
[dependencies]
11-
cxx = { version = "1.0.160", features = ["c++20"] }
9+
cxx = { version = "1.0.173", features = ["c++20"] }
1210

1311
[build-dependencies]
1412
cc = "1.2.16"
1513
cmake = "0.1.54"
1614
git2 = { version = "0.20.2", default-features = false, features = ["https"] }
17-
cxx-build = { version = "1.0.160", features = ["parallel"] }
15+
cxx-build = { version = "1.0.173", features = ["parallel"] }

src/tools/miri/genmc-sys/build.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ mod downloading {
2626
use super::GENMC_DOWNLOAD_PATH;
2727

2828
/// The GenMC repository the we get our commit from.
29-
pub(crate) const GENMC_GITHUB_URL: &str = "https://github.com/MPI-SWS/genmc.git";
29+
pub(crate) const GENMC_GITHUB_URL: &str = "https://gitlab.inf.ethz.ch/public-plf/genmc.git";
3030
/// The GenMC commit we depend on. It must be available on the specified GenMC repository.
31-
pub(crate) const GENMC_COMMIT: &str = "3438dd2c1202cd4a47ed7881d099abf23e4167ab";
31+
pub(crate) const GENMC_COMMIT: &str = "af9cc9ccd5d412b16defc35dbf36571c63a19c76";
3232

3333
pub(crate) fn download_genmc() -> PathBuf {
3434
let Ok(genmc_download_path) = PathBuf::from_str(GENMC_DOWNLOAD_PATH);
@@ -176,6 +176,11 @@ fn link_to_llvm(config_file: &Path) -> (String, String) {
176176

177177
/// Build the GenMC model checker library and the Rust-C++ interop library with cxx.rs
178178
fn compile_cpp_dependencies(genmc_path: &Path) {
179+
// Give each step a separate build directory to prevent interference.
180+
let out_dir = PathBuf::from(std::env::var("OUT_DIR").as_deref().unwrap());
181+
let genmc_build_dir = out_dir.join("genmc");
182+
let interface_build_dir = out_dir.join("miri_genmc");
183+
179184
// Part 1:
180185
// Compile the GenMC library using cmake.
181186

@@ -186,8 +191,11 @@ fn compile_cpp_dependencies(genmc_path: &Path) {
186191
let enable_genmc_debug = matches!(std::env::var("PROFILE").as_deref().unwrap(), "debug");
187192

188193
let mut config = cmake::Config::new(cmakelists_path);
189-
config.profile(GENMC_CMAKE_PROFILE);
190-
config.define("GENMC_DEBUG", if enable_genmc_debug { "ON" } else { "OFF" });
194+
config
195+
.always_configure(false) // We don't need to reconfigure on subsequent compilation runs.
196+
.out_dir(genmc_build_dir)
197+
.profile(GENMC_CMAKE_PROFILE)
198+
.define("GENMC_DEBUG", if enable_genmc_debug { "ON" } else { "OFF" });
191199

192200
// The actual compilation happens here:
193201
let genmc_install_dir = config.build();
@@ -210,6 +218,13 @@ fn compile_cpp_dependencies(genmc_path: &Path) {
210218
// These definitions are parsed into a cmake list and then printed to the config.h file, so they are ';' separated.
211219
let definitions = llvm_definitions.split(";");
212220

221+
let cpp_files = [
222+
"./cpp/src/MiriInterface/EventHandling.cpp",
223+
"./cpp/src/MiriInterface/Exploration.cpp",
224+
"./cpp/src/MiriInterface/Setup.cpp",
225+
"./cpp/src/MiriInterface/ThreadManagement.cpp",
226+
];
227+
213228
let mut bridge = cxx_build::bridge("src/lib.rs");
214229
// FIXME(genmc,cmake): Remove once the GenMC debug setting is available in the config.h file.
215230
if enable_genmc_debug {
@@ -225,32 +240,27 @@ fn compile_cpp_dependencies(genmc_path: &Path) {
225240
.std("c++23")
226241
.include(genmc_include_dir)
227242
.include(llvm_include_dirs)
228-
.include("./src_cpp")
229-
.file("./src_cpp/MiriInterface.hpp")
230-
.file("./src_cpp/MiriInterface.cpp")
243+
.include("./cpp/include")
244+
.files(&cpp_files)
245+
.out_dir(interface_build_dir)
231246
.compile("genmc_interop");
232247

233248
// Link the Rust-C++ interface library generated by cxx_build:
234249
println!("cargo::rustc-link-lib=static=genmc_interop");
235250
}
236251

237252
fn main() {
238-
// Make sure we don't accidentally distribute a binary with GPL code.
239-
if option_env!("RUSTC_STAGE").is_some() {
240-
panic!(
241-
"genmc should not be enabled in the rustc workspace since it includes a GPL dependency"
242-
);
243-
}
244-
245253
// Select which path to use for the GenMC repo:
246-
let genmc_path = if let Ok(genmc_src_path) = std::env::var("GENMC_SRC_PATH") {
254+
let genmc_path = if let Some(genmc_src_path) = option_env!("GENMC_SRC_PATH") {
247255
let genmc_src_path =
248256
PathBuf::from_str(&genmc_src_path).expect("GENMC_SRC_PATH should contain a valid path");
249257
assert!(
250258
genmc_src_path.exists(),
251259
"GENMC_SRC_PATH={} does not exist!",
252260
genmc_src_path.display()
253261
);
262+
// Rebuild files in the given path change.
263+
println!("cargo::rerun-if-changed={}", genmc_src_path.display());
254264
genmc_src_path
255265
} else {
256266
downloading::download_genmc()
@@ -265,5 +275,5 @@ fn main() {
265275
// cloned (since cargo detects that as a file modification).
266276
println!("cargo::rerun-if-changed={RUST_CXX_BRIDGE_FILE_PATH}");
267277
println!("cargo::rerun-if-changed=./src");
268-
println!("cargo::rerun-if-changed=./src_cpp");
278+
println!("cargo::rerun-if-changed=./cpp");
269279
}

0 commit comments

Comments
 (0)