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
extern crate bindgen;
use std::collections::HashSet;
use std::env;
use std::path::PathBuf;
#[derive(Debug)]
struct IgnoreMacros(HashSet<String>);
impl bindgen::callbacks::ParseCallbacks for IgnoreMacros {
fn will_parse_macro(&self, name: &str) -> bindgen::callbacks::MacroParsingBehavior {
if self.0.contains(name) {
bindgen::callbacks::MacroParsingBehavior::Ignore
} else {
bindgen::callbacks::MacroParsingBehavior::Default
}
}
}
// https://kornel.ski/rust-sys-crate
// NOTE: update linker cache before running: (when using dynamic linking to shared object)
// https://itsfoss.com/solve-open-shared-object-file-quick-tip/
// "sudo /sbin/ldconfig -v"
fn main() {
let mut path_with_graphblas_implementation = std::env::current_dir().unwrap();
path_with_graphblas_implementation.push("graphblas_implementation");
// Tell cargo to tell rustc to link the system GrapBLAS
// shared library.
println!(
"cargo:rustc-link-search=native={}",
path_with_graphblas_implementation
.clone()
.to_str()
.unwrap()
.to_owned()
);
// TODO: find directory with openMP archive gomp automatically
println!("cargo:rustc-link-search=native=/usr/lib/gcc/x86_64-linux-gnu/7/");
println!("cargo:rustc-link-lib=graphblas");
println!("cargo:rustc-link-lib=gomp");
// println!("cargo:rustc-link-lib=static=graphblas");
// println!("cargo:rustc-link-lib=static=gomp");
// Tell cargo to invalidate the built crate whenever the wrapper changes
println!(
"cargo:rerun-if-changed = {}",
path_with_graphblas_implementation
.clone()
.join("wrapper.h")
.to_str()
.unwrap()
.to_owned()
);
println!(
"cargo:rerun-if-changed = {}",
path_with_graphblas_implementation
.clone()
.join("GraphBLAS.h")
.to_str()
.unwrap()
.to_owned()
);
println!(
"cargo:rerun-if-changed = {}",
path_with_graphblas_implementation
.clone()
.join("libgraphblas.so")
.to_str()
.unwrap()
.to_owned()
);
let ignored_macros = IgnoreMacros(
vec![
"FP_INFINITE".into(),
"FP_NAN".into(),
"FP_NORMAL".into(),
"FP_SUBNORMAL".into(),
"FP_ZERO".into(),
"IPPORT_RESERVED".into(),
]
.into_iter()
.collect(),
);
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header(
path_with_graphblas_implementation
.clone()
.join("wrapper.h")
.to_str()
.unwrap()
.to_owned(),
)
// .header("GraphBLAS/wrapper.h")
.parse_callbacks(Box::new(ignored_macros))
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
// .parse_callbacks(Box::new(bindgen::CargoCallbacks))
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");
// Write the bindings to the bindings.rs file.
let mut bindings_target_path = std::env::current_dir().unwrap();
bindings_target_path.push("graphblas_implementation");
bindings_target_path.push("bindings.rs");
bindings
.write_to_file(bindings_target_path.to_str().unwrap().to_owned())
.expect("Couldn't write bindings!");
}