forked from sdwoodbury/audiopus_sys
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.rs
149 lines (125 loc) · 4.38 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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#![deny(rust_2018_idioms)]
#[cfg(feature = "generate_binding")]
use std::path::PathBuf;
use std::{env, fmt::Display, path::Path};
/// Outputs the library-file's prefix as word usable for actual arguments on
/// commands or paths.
const fn rustc_linking_word(is_static_link: bool) -> &'static str {
if is_static_link {
"static"
} else {
"dylib"
}
}
/// Generates a new binding at `src/lib.rs` using `src/wrapper.h`.
#[cfg(feature = "generate_binding")]
fn generate_binding() {
const ALLOW_UNCONVENTIONALS: &'static str = "#![allow(non_upper_case_globals)]\n\
#![allow(non_camel_case_types)]\n\
#![allow(non_snake_case)]\n";
let bindings = bindgen::Builder::default()
.header("src/wrapper.h")
.raw_line(ALLOW_UNCONVENTIONALS)
.generate()
.expect("Unable to generate binding");
let binding_target_path = PathBuf::new().join("src").join("lib.rs");
bindings
.write_to_file(binding_target_path)
.expect("Could not write binding to the file at `src/lib.rs`");
println!("cargo:info=Successfully generated binding.");
}
fn build_opus(is_static: bool) {
let opus_path = Path::new("opus");
println!(
"cargo:info=Opus source path used: {:?}.",
opus_path
.canonicalize()
.expect("Could not canonicalise to absolute path")
);
println!("cargo:info=Building Opus via CMake.");
let opus_build_dir = cmake::build(opus_path);
link_opus(is_static, opus_build_dir.display())
}
fn link_opus(is_static: bool, opus_build_dir: impl Display) {
let is_static_text = rustc_linking_word(is_static);
println!(
"cargo:info=Linking Opus as {} lib: {}",
is_static_text, opus_build_dir
);
println!("cargo:rustc-link-lib={}=opus", is_static_text);
println!("cargo:rustc-link-search=native={}/lib", opus_build_dir);
}
#[cfg(any(unix, target_env = "gnu"))]
fn find_via_pkg_config(is_static: bool) -> bool {
pkg_config::Config::new()
.statik(is_static)
.probe("opus")
.is_ok()
}
/// Based on the OS or target environment we are building for,
/// this function will return an expected default library linking method.
///
/// If we build for Windows, MacOS, or Linux with musl, we will link statically.
/// However, if you build for Linux without musl, we will link dynamically.
///
/// **Info**:
/// This is a helper-function and may not be called if
/// if the `static`-feature is enabled, the environment variable
/// `LIBOPUS_STATIC` or `OPUS_STATIC` is set.
fn default_library_linking() -> bool {
#[cfg(any(windows, target_os = "macos", target_env = "musl"))]
{
true
}
#[cfg(any(target_os = "freebsd", all(unix, target_env = "gnu")))]
{
false
}
}
fn find_installed_opus() -> Option<String> {
if let Ok(lib_directory) = env::var("LIBOPUS_LIB_DIR") {
Some(lib_directory)
} else if let Ok(lib_directory) = env::var("OPUS_LIB_DIR") {
Some(lib_directory)
} else {
None
}
}
fn is_static_build() -> bool {
if cfg!(feature = "static") && cfg!(feature = "dynamic") {
default_library_linking()
} else if cfg!(feature = "static")
|| env::var("LIBOPUS_STATIC").is_ok()
|| env::var("OPUS_STATIC").is_ok()
{
println!("cargo:info=Static feature or environment variable found.");
true
} else if cfg!(feature = "dynamic") {
println!("cargo:info=Dynamic feature enabled.");
false
} else {
println!("cargo:info=No feature or environment variable found, linking by default.");
default_library_linking()
}
}
fn main() {
#[cfg(feature = "generate_binding")]
generate_binding();
let is_static = is_static_build();
#[cfg(any(unix, target_env = "gnu"))]
{
if std::env::var("LIBOPUS_NO_PKG").is_ok() || std::env::var("OPUS_NO_PKG").is_ok() {
println!("cargo:info=Bypassed `pkg-config`.");
} else if find_via_pkg_config(is_static) {
println!("cargo:info=Found `Opus` via `pkg_config`.");
return;
} else {
println!("cargo:info=`pkg_config` could not find `Opus`.");
}
}
if let Some(installed_opus) = find_installed_opus() {
link_opus(is_static, installed_opus);
} else {
build_opus(is_static);
}
}