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
//
// Copyright (c) Memfault, Inc.
// See License.txt for details
use cc::Build;
use std::env;
use walkdir::WalkDir;
static LIBMEMFAULTC: &str = "libmemfaultc";
fn main() {
// Cross-compile C flags set by the CC Crate can conflict with the
// flags set by Yocto. Tell CC-rs to not set default flags.
env::set_var("CRATE_CC_NO_DEFAULTS", "true");
let mut cc = Build::new();
cc.flag("-fPIC");
cc.include(format!("{}/include", LIBMEMFAULTC));
cc.file(format!("{}/src/crash.c", LIBMEMFAULTC));
// Build a list of the library that we want to link into the final binary.
let mut libs = vec![];
if env::var("CARGO_FEATURE_SYSTEMD").is_ok() {
// Systemd is not available on macOS. We silently accept the feature so
// that the rust code can be checked but we don't actually build the C
// code.
if cfg!(not(target_os = "macos")) {
cc.file(format!("{}/src/systemd.c", LIBMEMFAULTC));
libs.push("libsystemd");
}
}
if env::var("CARGO_FEATURE_SWUPDATE").is_ok() {
cc.file(format!("{}/src/swupdate.c", LIBMEMFAULTC));
libs.push("libconfig");
}
// Linting needs to run `cargo` (and thus execute this file) to verify the
// project but the C dependencies are not installed on this machine. This
// environment variable will stop the script here, before doing any actual build.
// There is no standard Cargo way to tell if we are being called as part of `cargo lint`.
// See: https://github.com/rust-lang/cargo/issues/4001
if env::var("MEMFAULTD_SKIP_CMAKE").is_ok() {
return;
}
// Find required C libraries and tell Cargo how to link them
let pkg_config = pkg_config::Config::new();
libs.iter().for_each(|lib| {
// This line will print the required Cargo config if the library is found.
match pkg_config.probe(lib) {
Ok(lib) => {
cc.includes(lib.include_paths);
}
Err(e) => println!("WARNING - Library {} was not found: {}", lib, e),
}
});
// Build the libmemfaultc library and link tell Cargo to link it in the project
cc.compile("memfaultc");
println!("cargo:rustc-link-lib=static=memfaultc");
// Tell cargo to rebuild the project when any of the C project files changes
let root_src_dir = format!("{}/src", LIBMEMFAULTC);
WalkDir::new(root_src_dir)
.into_iter()
.filter_map(Result::ok)
.filter_map(
|e| match e.path().extension().and_then(std::ffi::OsStr::to_str) {
Some("c") => Some(e),
Some("h") => Some(e),
_ => None,
},
)
.for_each(|e| println!("cargo:rerun-if-changed={}", e.path().display()));
println!("cargo:rerun-if-changed=build.rs");
}