-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.rs
85 lines (70 loc) · 2.73 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
extern crate bindgen;
use std::env;
use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;
use std::io::BufWriter;
use std::io::Write;
use std::path::PathBuf;
use std::process::Command;
use regex::Regex;
fn main() {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
if cfg!(feature = "link-with-stub") {
let stubs_dir = out_path.join("stubs");
let current_dir = env::current_dir()
.expect("Can't get current directory");
if stubs_dir.exists() {
std::fs::remove_dir_all(&stubs_dir)
.expect("Can't remove stubs directory");
}
std::fs::create_dir_all(&stubs_dir)
.expect("Can't create stubs directory");
std::fs::copy(current_dir.join("dwf.h"), stubs_dir.join("dwf.h"))
.expect("Can't copy dwf.h to stubs directory");
println!("cargo:rustc-link-search=native={}", stubs_dir.to_string_lossy());
let stub_c = stubs_dir.join("dwf.c");
let mut out = BufWriter::new(File::create(&stub_c)
.expect(r###"Can't create "dwf.c""###));
writeln!(out, r###"#include "dwf.h""###).unwrap();
let fn_def_pattern = Regex::new(r###"DWFAPI BOOL (.*);.*"###).unwrap();
for line in BufReader::new(File::open("dwf.h")
.expect(r###"Can't open "dwf.h""###)).lines() {
if let Some(captures) = fn_def_pattern.captures(&line.unwrap()) {
let signature = captures.get(1).unwrap().as_str();
writeln!(out, "BOOL {} {{ return 0; }}", signature).unwrap();
}
}
drop(out);
let so_name = if cfg!(target_os = "linux") {
"libdwf.so"
} else if cfg!(target_os = "windows") {
"dwf.dll"
} else if cfg!(target_os = "macos") {
"libdwf.dylib"
} else {
unimplemented!("Only Linux, Mac OS and Windows are supported");
};
let stub_so = stubs_dir.join(so_name);
let mut cc_args = vec!["-shared"];
if !cfg!(target_os = "windows") {
cc_args.push("-fPIC");
}
cc_args.extend_from_slice(&["-x", "c++", "-o", stub_so.to_str().unwrap(), stub_c.to_str().unwrap()]);
let cc_out = Command::new("clang")
.args(&cc_args)
.output()
.expect("Failed to compile stub library");
if !cc_out.status.success() {
eprintln!("cc output: {:?}", cc_out);
}
}
println!("cargo:rustc-link-lib=dwf");
let bindings = bindgen::Builder::default()
.header("wrapper.h")
.generate()
.expect("Unable to generate bindings");
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}