-
Notifications
You must be signed in to change notification settings - Fork 5
/
build.rs
94 lines (87 loc) · 3.2 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
use std::path::PathBuf;
// SPDX-License-Identifier: LGPL-3.0
fn v(s: &str) -> versions::Versioning {
versions::Versioning::new(s).unwrap_or_else(|| panic!("could not parse version {}", s))
}
fn main() {
// this build script only depends on the wrapper
println!("cargo:rerun-if-changed=wrapper.hpp");
println!("cargo:rerun-if-changed=wrapper.cpp");
// find which version of nix we have
let nix = pkg_config::Config::new()
.atleast_version("2.2")
.probe("nix-main")
.unwrap();
eprintln!("Found nix version {}", &nix.version);
let nix_version = v(&nix.version);
// compile libnix_adapter.a
let mut builder = cc::Build::new();
builder
.cpp(true) // Switch to C++ library compilation.
.opt_level(2) // needed for fortify hardening included by nix
.includes(&nix.include_paths)
.file("wrapper.cpp");
let standard = if nix_version >= v("2.15") {
"-std=c++20" // for __VA_OPT__ in <nix/comparator.hh>
} else if nix_version >= v("2.3") {
"-std=c++17"
} else {
"-std=c++14"
};
builder.flag(standard);
let version = if nix_version >= v("2.19") {
219usize
} else if nix_version >= v("2.8") {
208usize
} else if nix_version >= v("2.7") {
207usize
} else if nix_version >= v("2.4") {
204
} else if nix_version >= v("2.3") {
203
} else if nix_version >= v("2.2") {
202
} else {
eprintln!("warning: could not compare version {nix_version} to known nix versions, attempting nix 2.8 wrapper");
208
};
eprintln!("building with NIXVER={version}");
builder.define("NIXVER", version.to_string().as_str());
let compiler = builder.get_compiler();
if compiler.is_like_clang() {
// required for exception handling with libc++ on darwin
// https://github.com/NixOS/nixpkgs/issues/166205
println!("cargo:rustc-link-lib=c++abi");
}
builder.compile("libnix_adapter.a");
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header("wrapper.hpp")
.allowlist_function("populateGraph")
.allowlist_type("path_t")
.opaque_type("std::.*")
.clang_arg(format!("-DNIXVER={}", version))
.clang_arg(standard)
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
// 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 $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(std::env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
/* must be passed as an argument to the linker *after* -lnix_adapter */
pkg_config::Config::new()
.atleast_version("2.2")
.probe("nix-store")
.unwrap();
pkg_config::Config::new()
.atleast_version("2.2")
.probe("nix-main")
.unwrap();
}