-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbuild.rs
More file actions
172 lines (149 loc) · 6.29 KB
/
Copy pathbuild.rs
File metadata and controls
172 lines (149 loc) · 6.29 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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
use std::fs;
use std::path::PathBuf;
use std::process::Command;
// -------------------------------------------------------------------------------------------------
fn main() {
println!("cargo:rerun-if-changed=src/lib.rs");
println!("cargo:rerun-if-changed=../vendor/flucoma-core/include/");
let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
let flucoma_dir = manifest_dir.join("..").join("vendor").join("flucoma-core");
let profile = match std::env::var("PROFILE").as_deref() {
Ok("release") => "Release",
_ => "RelWithDebInfo",
};
// -- cmake configure + build ALL_BUILD
let mut cmake_config = cmake::Config::new(&flucoma_dir);
cmake_config
.profile(profile)
.define("FOONATHAN_MEMORY_BUILD_TOOLS", "OFF")
.define("FOONATHAN_MEMORY_BUILD_EXAMPLES", "OFF")
.define("FOONATHAN_MEMORY_BUILD_TESTS", "OFF")
.define("BUILD_EXAMPLES", "OFF")
.define("FLUCOMA_TESTS", "OFF")
.define("FMT_INSTALL", "OFF");
if cfg!(target_env = "msvc") {
cmake_config.define(
// Use a msvc runtime library which is compatible with default Rust compiler settings
"CMAKE_MSVC_RUNTIME_LIBRARY",
"MultiThreaded$<$<CONFIG:Debug>:Debug>DLL",
);
// Enable C++ exception handling (required by foonathan/memory)
cmake_config.cxxflag("/EHsc");
} else {
// Disable all warnings
cmake_config.cxxflag("-w");
}
let cmake_out = cmake_config.build();
let cmake_build = cmake_out.join("build");
let deps_dir = cmake_build.join("_deps");
// -- configure and build foonathan_memory (required dependency)
let memory_build_dir = deps_dir.join("memory-build");
build_cmake_target(&memory_build_dir, "foonathan_memory", profile);
// Locate and link the foonathan_memory static library.
// The filename is versioned so we scan the directory to find the exact stem.
let (memory_lib_dir, memory_lib_stem) =
find_lib(&memory_build_dir.join("src"), profile, "foonathan_memory")
.or_else(|| find_lib(&memory_build_dir, profile, "foonathan_memory"))
.expect("could not find foonathan_memory library");
println!("cargo:rustc-link-search=all={}", memory_lib_dir.display());
println!("cargo:rustc-link-lib=static={}", memory_lib_stem);
// -- Add system lib dependencies
if cfg!(target_os = "macos") {
println!("cargo:rustc-link-lib=framework=Accelerate");
}
// -- Compile cpp! macro blocks via cpp_build
let eigen_include = deps_dir.join("eigen-src");
let hiss_include = deps_dir.join("hisstools-src").join("include");
let spectra_include = deps_dir.join("spectra-src").join("include");
let json_include = deps_dir.join("json-src").join("include");
let fmt_include = deps_dir.join("fmt-src").join("include");
let memory_config_include = memory_build_dir.join("src"); // config_impl.hpp
let memory_include = deps_dir
.join("memory-src")
.join("include")
.join("foonathan");
let mut build = cc::Build::new();
build
.cpp(true)
.static_crt(false) // match flucoma-core settings
.include(flucoma_dir.join("include"))
.include(&eigen_include)
.include(&hiss_include)
.include(&spectra_include)
.include(&json_include)
.include(&fmt_include)
.include(&memory_include)
.include(&memory_config_include)
.define("EIGEN_MPL2_ONLY", "1")
.define("FMT_HEADER_ONLY", "1")
.define("NOMINMAX", None)
.define("_USE_MATH_DEFINES", None);
if cfg!(target_env = "msvc") {
// Enable C++ exception handling (required by foonathan/memory)
build.flag("/EHsc").flag("/bigobj");
} else {
// Ignore all warnings
build.flag("-fpermissive").flag("-w");
}
// NB: add -std=c++17 via flag_if_supported to avoid that cpp_build appends a -std=c++11
let mut config: cpp_build::Config = build.clone().into();
config
.flag_if_supported("/std:c++17")
.flag_if_supported("-std=c++17")
.build("src/lib.rs");
}
// -------------------------------------------------------------------------------------------------
/// Build the ALL_BUILD target inside a cmake sub-directory.
fn build_cmake_target(dir: &PathBuf, label: &str, profile: &str) {
let mut cmd = Command::new("cmake");
cmd.arg("--build")
.arg(dir)
.arg("--config")
.arg(profile)
.arg("--parallel");
let status = cmd
.status()
.unwrap_or_else(|e| panic!("failed to run cmake --build for {}: {}", label, e));
if !status.success() {
panic!(
"cmake --build {} failed (exit code: {:?})",
label,
status.code()
);
}
}
// -------------------------------------------------------------------------------------------------
/// Find a static library whose filename contains `name` as stem.
fn find_lib(base: &PathBuf, profile: &str, name: &str) -> Option<(PathBuf, String)> {
// Scan `dir` for a `.lib` or `.a` file whose name contains `name`.
let lib_stem_in = |dir: &PathBuf, name: &str| -> Option<String> {
fs::read_dir(dir).ok()?.flatten().find_map(|e| {
let fname = e.file_name().to_string_lossy().to_string();
if fname.contains(name) && (fname.ends_with(".a") || fname.ends_with(".lib")) {
if fname.ends_with(".lib") {
// XXX.lib on windows
return fname.strip_suffix(".lib").map(String::from);
} else {
// libXXX.a on unix
return fname
.strip_prefix("lib")
.and_then(|s| s.strip_suffix(".a"))
.map(String::from);
}
}
None
})
};
// Try config-specific sub-dirs first (MSVC multi-config generators)
for sub in &[profile, "Release", "RelWithDebInfo", "Debug"] {
let d = base.join(sub);
if let Some(stem) = lib_stem_in(&d, name) {
return Some((d, stem));
}
}
// Fallback: directly in base (Unix Makefile / Ninja generators)
if let Some(stem) = lib_stem_in(base, name) {
return Some((base.clone(), stem));
}
None
}