Skip to content

Commit 60c9ef9

Browse files
committed
Allow including multiple backend solvers in cmake builds
1 parent eaae3b6 commit 60c9ef9

File tree

4 files changed

+176
-152
lines changed

4 files changed

+176
-152
lines changed

Diff for: CMakeLists.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,8 @@ else()
273273
FetchContent_MakeAvailable(Corrosion)
274274

275275
corrosion_import_crate(MANIFEST_PATH src/libcprover-rust/Cargo.toml)
276-
corrosion_set_env_vars(cprover-api-rust CBMC_BUILD_DIR=${CMAKE_BINARY_DIR} SAT_IMPL=${sat_impl})
276+
list(JOIN sat_impl " " sat_impl_str)
277+
corrosion_set_env_vars(cprover-api-rust CBMC_BUILD_DIR=${CMAKE_BINARY_DIR} "SAT_IMPL=${sat_impl_str}")
277278
corrosion_link_libraries(cprover-api-rust cprover-api-cpp)
278279
install(TARGETS cprover-api-rust RUNTIME DESTINATION lib)
279280
# NOTE: We want to rename to a name consistent with the name of the

Diff for: src/libcprover-rust/build.rs

+37-27
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,26 @@ fn get_cadical_build_dir() -> std::io::Result<PathBuf> {
4040
))
4141
}
4242

43-
fn get_sat_library() -> std::io::Result<&'static str> {
43+
fn get_sat_libraries() -> std::io::Result<Vec<&'static str>> {
4444
let env_var_name = "SAT_IMPL";
4545
let env_var_fetch_result = env::var(env_var_name);
46-
if let Ok(sat_impl) = env_var_fetch_result {
47-
let solver_lib = match sat_impl.as_str() {
48-
"minisat2" => Ok("minisat2-condensed"),
49-
"glucose" => Ok("glucose-condensed"),
50-
"cadical" => Ok("cadical"),
51-
_ => Err(Error::new(
52-
ErrorKind::Other,
53-
"no identifiable solver detected",
54-
)),
55-
};
56-
return solver_lib;
46+
if let Ok(sat_impls) = env_var_fetch_result {
47+
let mut solver_libs = Vec::new();
48+
for sat_impl in sat_impls.split(" ") {
49+
let solver_lib = match sat_impl {
50+
"minisat2" => "minisat2-condensed",
51+
"glucose" => "glucose-condensed",
52+
"cadical" => "cadical",
53+
_ => {
54+
return Err(Error::new(
55+
ErrorKind::Other,
56+
"no identifiable solver detected",
57+
))
58+
}
59+
};
60+
solver_libs.push(solver_lib);
61+
}
62+
return Ok(solver_libs);
5763
}
5864
Err(Error::new(
5965
ErrorKind::Other,
@@ -80,23 +86,25 @@ fn main() {
8086
Err(err) => panic!("Error: {}", err),
8187
};
8288

83-
let solver_lib = match get_sat_library() {
84-
Ok(solver) => solver,
89+
let solver_libs = match get_sat_libraries() {
90+
Ok(solvers) => solvers,
8591
Err(err) => panic!("Error: {}", err),
8692
};
8793

88-
// Cadical is being built in its own directory, with the resultant artefacts being
89-
// present only there. Hence, we need to instruct cargo to look for them in cadical's
90-
// build directory, otherwise we're going to get build errors.
91-
if solver_lib == "cadical" {
92-
let cadical_build_dir = match get_cadical_build_dir() {
93-
Ok(cadical_directory) => cadical_directory,
94-
Err(err) => panic!("Error: {}", err),
95-
};
96-
println!(
97-
"cargo:rustc-link-search=native={}",
98-
cadical_build_dir.display()
99-
);
94+
for solver_lib in solver_libs.iter() {
95+
// Cadical is being built in its own directory, with the resultant artefacts being
96+
// present only there. Hence, we need to instruct cargo to look for them in cadical's
97+
// build directory, otherwise we're going to get build errors.
98+
if *solver_lib == "cadical" {
99+
let cadical_build_dir = match get_cadical_build_dir() {
100+
Ok(cadical_directory) => cadical_directory,
101+
Err(err) => panic!("Error: {}", err),
102+
};
103+
println!(
104+
"cargo:rustc-link-search=native={}",
105+
cadical_build_dir.display()
106+
);
107+
}
100108
}
101109

102110
println!(
@@ -122,7 +130,9 @@ fn main() {
122130
println!("cargo:rustc-link-lib=static=statement-list");
123131
println!("cargo:rustc-link-lib=static=goto-symex");
124132
println!("cargo:rustc-link-lib=static=pointer-analysis");
125-
println!("cargo:rustc-link-lib=static={}", solver_lib);
133+
for solver_lib in solver_libs {
134+
println!("cargo:rustc-link-lib=static={}", solver_lib);
135+
}
126136
println!("cargo:rustc-link-lib=static=cbmc-lib");
127137
println!("cargo:rustc-link-lib=static=cprover-api-cpp");
128138
}

Diff for: src/solvers/CMakeLists.txt

+102-107
Original file line numberDiff line numberDiff line change
@@ -64,137 +64,132 @@ add_library(solvers ${sources})
6464

6565
include("${CBMC_SOURCE_DIR}/../cmake/DownloadProject.cmake")
6666

67-
if("${sat_impl}" STREQUAL "minisat2")
68-
message(STATUS "Building solvers with minisat2")
69-
70-
# once we upgrade to CMake 3.7 or higher we can specify multiple URLs as a
71-
# fall-back in case the first URL fails (the Makefile-based build retries up
72-
# to 2 times)
73-
download_project(PROJ minisat2
74-
URL http://ftp.debian.org/debian/pool/main/m/minisat2/minisat2_2.2.1.orig.tar.gz
75-
PATCH_COMMAND patch -p1 -i ${CBMC_SOURCE_DIR}/../scripts/minisat-2.2.1-patch
76-
COMMAND cmake -E copy ${CBMC_SOURCE_DIR}/../scripts/minisat2_CMakeLists.txt CMakeLists.txt
77-
URL_MD5 27faa19ee0508660bd6fb7f894646d42
78-
)
67+
foreach(SOLVER ${sat_impl})
68+
if("${SOLVER}" STREQUAL "minisat2")
69+
message(STATUS "Building solvers with minisat2")
70+
71+
# once we upgrade to CMake 3.7 or higher we can specify multiple URLs as a
72+
# fall-back in case the first URL fails (the Makefile-based build retries up
73+
# to 2 times)
74+
download_project(PROJ minisat2
75+
URL http://ftp.debian.org/debian/pool/main/m/minisat2/minisat2_2.2.1.orig.tar.gz
76+
PATCH_COMMAND patch -p1 -i ${CBMC_SOURCE_DIR}/../scripts/minisat-2.2.1-patch
77+
COMMAND cmake -E copy ${CBMC_SOURCE_DIR}/../scripts/minisat2_CMakeLists.txt CMakeLists.txt
78+
URL_MD5 27faa19ee0508660bd6fb7f894646d42
79+
)
7980

80-
add_subdirectory(${minisat2_SOURCE_DIR} ${minisat2_BINARY_DIR})
81+
add_subdirectory(${minisat2_SOURCE_DIR} ${minisat2_BINARY_DIR})
8182

82-
target_compile_definitions(solvers PUBLIC
83-
SATCHECK_MINISAT2 HAVE_MINISAT2 __STDC_FORMAT_MACROS __STDC_LIMIT_MACROS
84-
)
85-
86-
target_sources(solvers PRIVATE ${minisat2_source})
83+
target_compile_definitions(solvers PUBLIC
84+
SATCHECK_MINISAT2 HAVE_MINISAT2 __STDC_FORMAT_MACROS __STDC_LIMIT_MACROS
85+
)
8786

88-
target_link_libraries(solvers minisat2-condensed)
89-
elseif("${sat_impl}" STREQUAL "glucose")
90-
message(STATUS "Building solvers with glucose")
87+
target_sources(solvers PRIVATE ${minisat2_source})
9188

92-
download_project(PROJ glucose
93-
URL https://github.com/BrunoDutertre/glucose-syrup/archive/0bb2afd3b9baace6981cbb8b4a1c7683c44968b7.tar.gz
94-
PATCH_COMMAND patch -p1 -i ${CBMC_SOURCE_DIR}/../scripts/glucose-syrup-patch
95-
COMMAND cmake -E copy ${CBMC_SOURCE_DIR}/../scripts/glucose_CMakeLists.txt CMakeLists.txt
96-
URL_MD5 7c539c62c248b74210aef7414787323a
97-
)
89+
target_link_libraries(solvers minisat2-condensed)
90+
elseif("${SOLVER}" STREQUAL "glucose")
91+
message(STATUS "Building solvers with glucose")
9892

99-
add_subdirectory(${glucose_SOURCE_DIR} ${glucose_BINARY_DIR})
93+
download_project(PROJ glucose
94+
URL https://github.com/BrunoDutertre/glucose-syrup/archive/0bb2afd3b9baace6981cbb8b4a1c7683c44968b7.tar.gz
95+
PATCH_COMMAND patch -p1 -i ${CBMC_SOURCE_DIR}/../scripts/glucose-syrup-patch
96+
COMMAND cmake -E copy ${CBMC_SOURCE_DIR}/../scripts/glucose_CMakeLists.txt CMakeLists.txt
97+
URL_MD5 7c539c62c248b74210aef7414787323a
98+
)
10099

101-
target_compile_definitions(solvers PUBLIC
102-
SATCHECK_GLUCOSE HAVE_GLUCOSE __STDC_FORMAT_MACROS __STDC_LIMIT_MACROS
103-
)
100+
add_subdirectory(${glucose_SOURCE_DIR} ${glucose_BINARY_DIR})
104101

105-
target_sources(solvers PRIVATE ${glucose_source})
102+
target_compile_definitions(solvers PUBLIC
103+
SATCHECK_GLUCOSE HAVE_GLUCOSE __STDC_FORMAT_MACROS __STDC_LIMIT_MACROS
104+
)
106105

107-
target_link_libraries(solvers glucose-condensed)
108-
elseif("${sat_impl}" STREQUAL "cadical")
109-
message(STATUS "Building solvers with cadical")
106+
target_sources(solvers PRIVATE ${glucose_source})
110107

111-
download_project(PROJ cadical
112-
URL https://github.com/arminbiere/cadical/archive/rel-1.4.1.tar.gz
113-
PATCH_COMMAND true
114-
COMMAND CXX=${CMAKE_CXX_COMPILER} ./configure -O3 -s CXXFLAGS=-std=c++14
115-
URL_MD5 b44874501a175106424f4bd5de29aa59
116-
)
108+
target_link_libraries(solvers glucose-condensed)
109+
elseif("${SOLVER}" STREQUAL "cadical")
110+
message(STATUS "Building solvers with cadical")
117111

118-
message(STATUS "Building CaDiCaL")
119-
execute_process(COMMAND make -j WORKING_DIRECTORY ${cadical_SOURCE_DIR})
112+
download_project(PROJ cadical
113+
URL https://github.com/arminbiere/cadical/archive/rel-1.4.1.tar.gz
114+
PATCH_COMMAND patch -p1 -i ${CBMC_SOURCE_DIR}/../scripts/cadical-1.4.1-patch
115+
COMMAND cmake -E copy ${CBMC_SOURCE_DIR}/../scripts/cadical_CMakeLists.txt CMakeLists.txt
116+
COMMAND ./configure
117+
URL_MD5 b44874501a175106424f4bd5de29aa59
118+
)
120119

121-
target_compile_definitions(solvers PUBLIC
122-
SATCHECK_CADICAL HAVE_CADICAL
123-
)
120+
add_subdirectory(${cadical_SOURCE_DIR} ${cadical_BINARY_DIR})
124121

125-
add_library(cadical STATIC IMPORTED)
122+
target_compile_definitions(solvers PUBLIC
123+
SATCHECK_CADICAL HAVE_CADICAL
124+
)
126125

127-
set_target_properties(
128-
cadical
129-
PROPERTIES IMPORTED_LOCATION ${cadical_SOURCE_DIR}/build/libcadical.a
130-
)
126+
target_include_directories(solvers
127+
PUBLIC
128+
${cadical_SOURCE_DIR}/src
129+
)
131130

132-
target_include_directories(solvers
133-
PUBLIC
134-
${cadical_SOURCE_DIR}/src
135-
)
131+
target_link_libraries(solvers cadical)
132+
elseif("${SOLVER}" STREQUAL "ipasir-cadical")
133+
message(STATUS "Building with IPASIR solver linking against: CaDiCaL")
136134

137-
target_link_libraries(solvers cadical)
138-
elseif("${sat_impl}" STREQUAL "ipasir-cadical")
139-
message(STATUS "Building with IPASIR solver linking against: CaDiCaL")
135+
download_project(PROJ cadical
136+
URL https://github.com/arminbiere/cadical/archive/rel-1.4.1.tar.gz
137+
PATCH_COMMAND true
138+
COMMAND CXX=${CMAKE_CXX_COMPILER} ./configure -O3 -s CXXFLAGS=-std=c++14
139+
URL_MD5 b44874501a175106424f4bd5de29aa59
140+
)
140141

141-
download_project(PROJ cadical
142-
URL https://github.com/arminbiere/cadical/archive/rel-1.4.1.tar.gz
143-
PATCH_COMMAND true
144-
COMMAND CXX=${CMAKE_CXX_COMPILER} ./configure -O3 -s CXXFLAGS=-std=c++14
145-
URL_MD5 b44874501a175106424f4bd5de29aa59
146-
)
142+
message(STATUS "Building CaDiCaL")
143+
execute_process(COMMAND make WORKING_DIRECTORY ${cadical_SOURCE_DIR})
147144

148-
message(STATUS "Building CaDiCaL")
149-
execute_process(COMMAND make WORKING_DIRECTORY ${cadical_SOURCE_DIR})
145+
target_compile_definitions(solvers PUBLIC
146+
SATCHECK_IPASIR HAVE_IPASIR IPASIR=${cadical_SOURCE_DIR}/src
147+
)
150148

151-
target_compile_definitions(solvers PUBLIC
152-
SATCHECK_IPASIR HAVE_IPASIR IPASIR=${cadical_SOURCE_DIR}/src
153-
)
149+
add_library(cadical_ipasir STATIC IMPORTED)
150+
set_property(TARGET cadical_ipasir
151+
PROPERTY IMPORTED_LOCATION ${cadical_SOURCE_DIR}/build/libcadical.a
152+
)
154153

155-
add_library(cadical_ipasir STATIC IMPORTED)
156-
set_property(TARGET cadical_ipasir
157-
PROPERTY IMPORTED_LOCATION ${cadical_SOURCE_DIR}/build/libcadical.a
158-
)
154+
target_include_directories(solvers
155+
PUBLIC
156+
${cadical_SOURCE_DIR}/src
157+
)
158+
target_link_libraries(solvers cadical_ipasir)
159+
elseif("${SOLVER}" STREQUAL "ipasir-custom")
160+
message(STATUS "Building with IPASIR solver linking: custom solver provided")
161+
162+
if (NOT DEFINED IPASIR)
163+
message(FATAL_ERROR
164+
"IPASIR solver source code not provided. Please use -DIPASIR=<location> "
165+
"with <location> being the path to the IPASIR solver source code."
166+
)
167+
endif()
168+
169+
if (NOT DEFINED IPASIR_LIB)
170+
message(FATAL_ERROR
171+
"IPASIR solver library not provided. Please use -DIPASIR_LIB=<location> "
172+
"with <location> being the path to the IPASIR solver precompiled static "
173+
"library."
174+
)
175+
endif()
176+
177+
target_compile_definitions(solvers PUBLIC
178+
SATCHECK_IPASIR HAVE_IPASIR IPASIR=${IPASIR}
179+
)
159180

160-
target_include_directories(solvers
161-
PUBLIC
162-
${cadical_SOURCE_DIR}/src
163-
)
164-
target_link_libraries(solvers cadical_ipasir)
165-
elseif("${sat_impl}" STREQUAL "ipasir-custom")
166-
message(STATUS "Building with IPASIR solver linking: custom solver provided")
167-
168-
if (NOT DEFINED IPASIR)
169-
message(FATAL_ERROR
170-
"IPASIR solver source code not provided. Please use -DIPASIR=<location> "
171-
"with <location> being the path to the IPASIR solver source code."
181+
add_library(ipasir_custom STATIC IMPORTED)
182+
set_property(TARGET ipasir_custom
183+
PROPERTY IMPORTED_LOCATION ${IPASIR_LIB}
172184
)
173-
endif()
174185

175-
if (NOT DEFINED IPASIR_LIB)
176-
message(FATAL_ERROR
177-
"IPASIR solver library not provided. Please use -DIPASIR_LIB=<location> "
178-
"with <location> being the path to the IPASIR solver precompiled static "
179-
"library."
186+
target_include_directories(solvers
187+
PUBLIC
188+
${IPASIR}
180189
)
190+
target_link_libraries(solvers ipasir_custom pthread)
181191
endif()
182-
183-
target_compile_definitions(solvers PUBLIC
184-
SATCHECK_IPASIR HAVE_IPASIR IPASIR=${IPASIR}
185-
)
186-
187-
add_library(ipasir_custom STATIC IMPORTED)
188-
set_property(TARGET ipasir_custom
189-
PROPERTY IMPORTED_LOCATION ${IPASIR_LIB}
190-
)
191-
192-
target_include_directories(solvers
193-
PUBLIC
194-
${IPASIR}
195-
)
196-
target_link_libraries(solvers ipasir_custom pthread)
197-
endif()
192+
endforeach()
198193

199194
if(CMAKE_USE_CUDD)
200195
target_link_libraries(solvers util cudd-cplusplus cudd)

0 commit comments

Comments
 (0)