-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathbuild.rs
More file actions
134 lines (108 loc) · 4.36 KB
/
build.rs
File metadata and controls
134 lines (108 loc) · 4.36 KB
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
use std::env;
use std::path::Path;
use anyhow::Context;
fn main() {
let flags = build_flags();
build_joltc();
generate_bindings(&flags).unwrap();
}
fn build_joltc() {
let mut config = cmake::Config::new("JoltC");
// We always have to build in Release.
//
// On Windows, Rust always links against the non-debug CRT. Using the Debug
// profile (which the cmake crate will sometimes pick by default) causes
// Jolt/JoltC to be linked against the debug CRT, causing linker issues.
//
// Forcing Jolt and JoltC to be compiled with the non-debug CRT (/MT)
// doesn't change enough about the build to work.
//
// As a nice side effect, this ensures that we build with a known
// configuration instead of accidentally enabling or disabling extra
// features just based on opt-level.
config.profile("Release");
// Jolt fails to compile via the cmake crate without specifying exception
// handling behavior under MSVC. I'm not sure that this is the correct
// exception handling mode.
if cfg!(windows) {
config.cxxflag("/EHsc");
}
// Having IPO/LTO turned on breaks lld on Windows.
config.define("INTERPROCEDURAL_OPTIMIZATION", "OFF");
// Warnings when building Jolt or JoltC don't matter to users of joltc-sys.
config.define("ENABLE_ALL_WARNINGS", "OFF");
// These feature flags go through CMake and affect compilation of both Jolt
// and JoltC.
if cfg!(feature = "double-precision") {
config.define("DOUBLE_PRECISION", "ON");
}
if cfg!(feature = "object-layer-u32") {
config.define("OBJECT_LAYER_BITS", "32");
}
if cfg!(feature = "asserts") {
config.define("USE_ASSERTS", "ON");
}
let mut dst = config.build();
// Jolt and JoltC put libraries in the 'lib' subfolder. This goes against
// the docs of the cmake crate, but it's possible that it's just mishandling
// an output path and not account for the install target's configurability.
dst.push("lib");
println!("cargo:rustc-link-search=native={}", dst.display());
// On Fedora Workstation 42, it looks like Jolt puts libs in the "lib64"
// subfolder, so make sure to search there too.
dst.pop();
dst.push("lib64");
println!("cargo:rustc-link-search=native={}", dst.display());
link();
// On macOS and Linux, we need to explicitly link against the C++ standard
// library here to avoid getting missing symbol errors from Jolt/JoltC.
if cfg!(target_os = "macos") {
println!("cargo:rustc-flags=-l dylib=c++");
}
if cfg!(target_os = "linux") {
println!("cargo:rustc-link-lib=dylib=stdc++");
}
}
fn link() {
println!("cargo:rustc-link-lib=joltc");
println!("cargo:rustc-link-lib=Jolt");
}
/// Generate build flags specifically for generating bindings.
///
/// This is redundant with Jolt and JoltC's CMake files, which do this mapping
/// for us, but we're unable to leverage that config when running bindgen.
fn build_flags() -> Vec<(&'static str, &'static str)> {
let mut flags = Vec::new();
// Force the debug renderer on. In the future, we might want to tie this to
// a crate feature.
flags.push(("JPH_DEBUG_RENDERER", "ON"));
// It's important that these flags are never out of sync for Jolt and JoltC.
if cfg!(feature = "double-precision") {
flags.push(("JPC_DOUBLE_PRECISION", "ON"));
flags.push(("JPH_DOUBLE_PRECISION", "ON"));
}
if cfg!(feature = "object-layer-u32") {
flags.push(("JPC_OBJECT_LAYER_BITS", "32"));
flags.push(("JPH_OBJECT_LAYER_BITS", "32"));
}
flags
}
fn generate_bindings(flags: &[(&'static str, &'static str)]) -> anyhow::Result<()> {
let mut builder = bindgen::Builder::default()
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.header("JoltC/JoltC/JoltC.h")
.clang_arg("-IJoltC")
.allowlist_item("JPC_.*")
.default_enum_style(bindgen::EnumVariation::Consts)
.prepend_enum_name(false);
for (key, value) in flags {
builder = builder.clang_arg(format!("-D{key}={value}"));
}
let bindings = builder
.generate()
.context("failed to generate JoltC bindings")?;
let out_path = Path::new(&env::var("OUT_DIR").unwrap()).join("bindings.rs");
bindings
.write_to_file(out_path)
.context("Couldn't write bindings!")
}