use std::env;
use std::env::VarError;
use std::io::{Error, ErrorKind};
use std::path::PathBuf;
fn get_current_working_dir() -> std::io::Result<PathBuf> {
env::current_dir()
}
fn get_cbmc_version() -> Result<String, VarError> {
env::var("CBMC_VERSION")
}
fn get_lib_directory() -> Result<String, VarError> {
env::var("CBMC_LIB_DIR")
}
fn get_library_build_dir() -> std::io::Result<PathBuf> {
let env_var_fetch_result = get_lib_directory();
if let Ok(build_dir) = env_var_fetch_result {
let mut path = PathBuf::new();
path.push(build_dir);
return Ok(path);
}
Err(Error::new(
ErrorKind::Other,
"Environment variable `CBMC_LIB_DIR' not set",
))
}
fn get_include_directory_envvar() -> Result<String, VarError> {
env::var("CBMC_INCLUDE_DIR")
}
fn get_include_directory() -> std::io::Result<PathBuf> {
let env_var_fetch_result = get_include_directory_envvar();
if let Ok(build_dir) = env_var_fetch_result {
let mut path = PathBuf::new();
path.push(build_dir);
return Ok(path);
}
Err(Error::new(
ErrorKind::Other,
"Environment variable `CBMC_INCLUDE_DIR' not set",
))
}
fn main() {
let cpp_api_include_path = match get_include_directory() {
Ok(path) => path,
Err(err) => {
let error_message = &format!(
"Error: {}.\n Advice: {}.",
err,
"Please set the environment variable `CBMC_INCLUDE_DIR' with the path that contains cprover/api.h on your system"
);
panic!("{}", error_message);
}
};
let _build = cxx_build::bridge("src/lib.rs")
.include(cpp_api_include_path)
.include(get_current_working_dir().unwrap())
.file("src/c_api.cc")
.flag_if_supported("-std=c++17")
.compile("cprover-rust-api");
println!("cargo:rerun-if-changed=src/c_api.cc");
println!("cargo:rerun-if-changed=include/c_api.h");
let libraries_path = match get_library_build_dir() {
Ok(path) => path,
Err(err) => {
let error_message = &format!(
"Error: {}.\n Advice: {}.",
err,
"Please set the environment variable `CBMC_LIB_DIR' with the path that contains libcprover.x.y.z.a on your system"
);
panic!("{}", error_message);
}
};
println!(
"cargo:rustc-link-search=native={}",
libraries_path.display()
);
let cprover_static_libname = match get_cbmc_version() {
Ok(version) => String::from("cprover.") + &version,
Err(_) => {
let error_message = &format!(
"Error: {}.\n Advice: {}.",
"Environment variable `CBMC_VERSION' not set",
"Please set the environment variable `CBMC_VERSION' with the version of CBMC you want to link against (e.g. 5.78.0)"
);
panic!("{}", error_message);
}
};
println!("cargo:rustc-link-lib=static={}", cprover_static_libname);
}