forked from mmaroti/cadical-rs
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbuild.rs
182 lines (149 loc) · 6.5 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//! Build script for ccadical.
//! This script is responsible for compiling the cadical C++ library.
//! For more information:
//! <https://doc.rust-lang.org/cargo/reference/build-scripts.html>
//! <https://doc.rust-lang.org/cargo/reference/build-script-examples.html>
// ************************************************************************************************
// use
// ************************************************************************************************
use std::{env, fs, path::Path, process::Command};
// ************************************************************************************************
// constants
// ************************************************************************************************
const CADICAL_PATH: &str = "cadical";
// ************************************************************************************************
// Compile using cc crate
// ************************************************************************************************
fn _compile_using_cc() {
let mut build = cc::Build::new();
// set to c++
build.cpp(true).flag_if_supported("-std=c++11");
// disable default flags
// build.no_default_flags(true);
// add the flags used by cadical 'configure: compiling with 'g++ -Wall -Wextra -O3 -DNDEBUG -DNBUILD'
// this adds -Wall and -Wextra
build.warnings(true);
// define pre compilation variables
build.define("NDEBUG", None);
build.define("NBUILD", None);
build.define("NUNLOCKED", None);
build.define("NTRACING", None);
build.define("QUIET", None);
let version = std::fs::read_to_string(format!("{CADICAL_PATH}/VERSION"));
let version = version.expect("missing cadical submodule");
let version = format!("\"{}\"", version.trim());
build.define("VERSION", version.as_ref());
// assertions only for debug builds with debug feature enabled
if std::env::var("PROFILE").unwrap() == "debug"
&& std::env::var("CARGO_FEATURE_CPP_DEBUG").is_ok()
{
build.debug(true);
} else {
build.debug(false).opt_level(3).define("NDEBUG", None);
}
// create list of files to compile
let mut files = vec![];
// add interface that we added
files.push("src/ccadical.cpp".to_string());
// add cadical .cpp files
let dir_entries = fs::read_dir(format!("{CADICAL_PATH}/src")).unwrap();
for path in dir_entries {
let dir_entry = path.unwrap();
let path = dir_entry.path();
let path_str = path.to_str().unwrap().to_string();
if std::path::Path::new(&path_str)
.extension()
.map_or(false, |ext| ext.eq_ignore_ascii_case("cpp"))
// mobical should be ignored
&& (!path_str.ends_with("/mobical.cpp"))
// added later
&& (!path_str.ends_with("/resources.cpp"))
// added later
&& (!path_str.ends_with("/lookahead.cpp"))
// already added in src/ccadical.cpp
&& (!path_str.ends_with("/ccadical.cpp"))
// contains another main function
&& (!path_str.ends_with("/cadical.cpp"))
{
// eprintln!("Compiling path {}", path_str);
files.push(path_str);
}
}
// add resources and lookahead files
if build.get_compiler().is_like_msvc() {
build.include(std::path::Path::new("src/msvc"));
files.push("src/msvc/resources.cpp".to_string());
files.push("src/msvc/lookahead.cpp".to_string());
} else {
files.push(format!("{CADICAL_PATH}/src/resources.cpp"));
files.push(format!("{CADICAL_PATH}/src/lookahead.cpp"));
}
// add files which will be compiled
build.files(files.iter());
// tell the compiler to recompile if any of the files changed
for file in &files {
println!("cargo:rerun-if-changed={file}");
}
println!("cargo:rerun-if-env-changed=CC");
println!("cargo:rerun-if-env-changed=CFLAGS");
println!("cargo:rerun-if-env-changed=CXX");
println!("cargo:rerun-if-env-changed=CXXFLAGS");
println!("cargo:rerun-if-env-changed=CXXSTDLIB");
println!("cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS");
// link the standard library if needed (this fixes errors when using Clang)
if build.get_compiler().is_like_clang() {
build.cpp_set_stdlib("c++");
}
// compile
build.compile("ccadical");
}
// ************************************************************************************************
// Compile using the ./config && make script
// ************************************************************************************************
fn _run_command(command: &mut Command) {
let command_str = format!("{command:?}");
match command.output() {
Ok(_) => println!("cargo:warning=Command {command_str} was successful"),
Err(e) => {
panic!("Failed to execute command:\n{}\nERROR:\n{}", command_str, e);
}
}
}
fn _change_directory(path: &str) {
match env::set_current_dir(Path::new(path)) {
Ok(()) => println!(
"cargo:warning=Changed working directory to {}",
env::current_dir().unwrap().display()
),
Err(e) => panic!("Failed to change directory to:\n{}\nERROR:\n{}", path, e),
}
}
fn _make_dir(dir: &str) {
match fs::create_dir_all(dir) {
Ok(()) => println!("cargo:warning=Created directory {dir}"),
Err(e) => panic!("Failed to create directory:\n{}\nERROR:\n{}", dir, e),
}
}
/// Not ready yet, mainly there are issues with using cargo clean to clean the build.
/// The problem is that cargo clean will delete the target directory,
/// which will does not delete the cadical build. Both solutions of either performing
/// "make clean" on build or making the script compile into target ran into issues.
fn _compile_using_cadical_script() {
// always recompile when anything changes
// println!("cargo:rerun-if-changed=/{}", CADICAL_PATH);
// change working directory to cadical
_change_directory(format!("./{CADICAL_PATH}").as_ref());
// clean previous build
// _run_command(Command::new("make").arg("clean"));
// configure makefile
_run_command(&mut Command::new("./configure"));
// compile
_run_command(&mut Command::new("make"));
panic!();
}
// ************************************************************************************************
// Main build function
// ************************************************************************************************
fn main() {
_compile_using_cc();
}