-
Notifications
You must be signed in to change notification settings - Fork 1
/
build.rs
118 lines (103 loc) · 4.11 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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use std::path::PathBuf;
pub fn cargo_rerun_if_env_changed(target: &str, env_var: &str) {
println!("cargo:rerun-if-env-changed={env_var}");
println!("cargo:rerun-if-env-changed={env_var}_{target}");
println!(
"cargo:rerun-if-env-changed={}_{}",
env_var,
target.replace('-', "_")
);
}
pub fn get_target_env_var(target: &str, env_var: &str) -> Option<String> {
std::env::var(format!("{env_var}_{target}"))
.or_else(|_| std::env::var(format!("{}_{}", env_var, target.replace('-', "_"))))
.or_else(|_| std::env::var(env_var))
.ok()
}
fn main() {
let target = std::env::var("TARGET").unwrap();
let libdir = PathBuf::from("authenticode-parser");
let srcdir = libdir.join("src");
cargo_rerun_if_env_changed(&target, "OPENSSL_DIR");
cargo_rerun_if_env_changed(&target, "OPENSSL_INCLUDE_DIR");
cargo_rerun_if_env_changed(&target, "OPENSSL_LIB_DIR");
// If OPENSSL_DIR is set, use it to extrapolate lib and include dir
let mut openssl_include_dir = None;
if let Some(openssl_dir) = get_target_env_var(&target, "OPENSSL_DIR") {
let openssl_dir = PathBuf::from(openssl_dir);
openssl_include_dir = Some(openssl_dir.join("include"));
println!(
"cargo:rustc-link-search=native={}",
openssl_dir.join("lib").display()
);
} else {
// Otherwise, retrieve OPENSSL_INCLUDE_DIR and OPENSSL_LIB_DIR
if let Some(include_dir) = get_target_env_var(&target, "OPENSSL_INCLUDE_DIR") {
openssl_include_dir = Some(PathBuf::from(include_dir));
}
if let Some(openssl_lib_dir) = get_target_env_var(&target, "OPENSSL_LIB_DIR") {
println!(
"cargo:rustc-link-search=native={}",
PathBuf::from(openssl_lib_dir).display()
);
}
}
// Build the lib. This is copied from its CMakeLists.txt.
let mut builder = cc::Build::new();
#[cfg(target_endian = "big")]
builder.define("WORDS_BIGENDIAN", "");
builder
.file(srcdir.join("authenticode.c"))
.file(srcdir.join("helper.c"))
.file(srcdir.join("structs.c"))
.file(srcdir.join("countersignature.c"))
.file(srcdir.join("certificate.c"))
.include(libdir.join("include"));
if let Some(include_dir) = openssl_include_dir {
builder.include(include_dir);
}
builder.compile("authenticode-parser");
let link_mode = if cfg!(feature = "openssl-static") {
"static"
} else {
"dylib"
};
// Link to the built library, and to the openssl dependency
if target.contains("windows-msvc") {
println!("cargo:rustc-link-lib={}=libcrypto", link_mode);
println!("cargo:rustc-link-lib=dylib=user32");
println!("cargo:rustc-link-lib=dylib=crypt32");
} else {
println!("cargo:rustc-link-lib={}=crypto", link_mode);
}
#[cfg(feature = "bindgen")]
generate_bindings(&libdir);
}
#[cfg(feature = "bindgen")]
fn generate_bindings(libdir: &std::path::Path) {
// Generate bindings using bindgen.
// If https://github.com/avast/authenticode-parser/pull/12 is fixed, this could be removed :(
let bindings = bindgen::Builder::default()
.clang_arg(format!("-I{}", libdir.join("include").display()))
.header(
libdir
.join("include")
.join("authenticode-parser")
.join("authenticode.h")
.display()
.to_string(),
)
.allowlist_function("initialize_authenticode_parser")
.allowlist_function("parse_authenticode")
.allowlist_function("authenticode_new")
.allowlist_function("authenticode_array_free")
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("Unable to generate bindings");
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!");
}