-
Notifications
You must be signed in to change notification settings - Fork 1
/
build.rs
89 lines (80 loc) · 2.75 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
use std::env;
use std::path::PathBuf;
use bindgen::callbacks::ParseCallbacks;
fn main() {
// First ensure that appropriate version of HarfBuzz exists
let include_paths = if cfg!(feature = "bundled") {
build_harfbuzz()
} else {
pkg_config::probe_library("harfbuzz-subset")
.unwrap()
.include_paths
};
// Then build the sys bindings
build_bindings(include_paths);
}
fn build_harfbuzz() -> Vec<PathBuf> {
cc::Build::new()
.cpp(true)
.flag("-std=c++11")
.warnings(false)
.file("harfbuzz/src/harfbuzz-subset.cc")
.compile("embedded-harfbuzz-subset");
println!("cargo:rerun-if-changed=harfbuzz/src");
vec!["harfbuzz/src/".into()]
}
fn build_bindings(include_paths: Vec<PathBuf>) {
let bindings = bindgen::Builder::default()
.clang_args(
include_paths
.into_iter()
.map(|path| format!("-I{}", path.display())),
)
.header("wrapper.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.parse_callbacks(Box::new(NoCommentsCallback))
.allowlist_item("hb_.*")
.bitfield_enum("hb_subset_flags_t")
.bitfield_enum("hb_subset_sets_t")
.bitfield_enum("hb_ot_name_id_predefined_t")
.new_type_alias("hb_ot_name_id_t")
.generate()
.expect("Unable to generate bindings");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}
/// [`ParseCallbacks`] which make Bindgen generate no comments.
///
/// This is because Bindgen does not properly support the style of comments used in the C headers, and hence emitting
/// them to Rust code adds only unnecessary noise.
#[derive(Debug)]
struct NoCommentsCallback;
impl ParseCallbacks for NoCommentsCallback {
fn process_comment(&self, _comment: &str) -> Option<String> {
Some("".into())
}
fn enum_variant_name(
&self,
enum_name: Option<&str>,
original_variant_name: &str,
_variant_value: bindgen::callbacks::EnumVariantValue,
) -> Option<String> {
if enum_name == Some("hb_subset_sets_t") {
original_variant_name
.strip_prefix("HB_SUBSET_SETS_")
.map(String::from)
} else if enum_name == Some("hb_subset_flags_t") {
original_variant_name
.strip_prefix("HB_SUBSET_FLAGS_")
.map(String::from)
} else if enum_name == Some("hb_ot_name_id_predefined_t") {
original_variant_name
.strip_prefix("HB_OT_NAME_ID_")
.map(String::from)
} else {
None
}
}
}