forked from nrf-rs/nrfxlib-sys
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.rs
126 lines (104 loc) · 5.47 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
//! Build Script for nrfxlib-sys
//!
//! Calls out to bindgen to generate a Rust crate from the Nordic header
//! files.
const LIBOBERON_PATH: &str = "crypto/nrf_oberon/lib/cortex-m33/hard-float/liboberon_3.0.15.a";
const LIBCC310_PATH: &str = "crypto/nrf_cc310_platform/lib/cortex-m33/hard-float/no-interrupts/libnrf_cc310_platform_0.9.19.a";
const LIBFUEL_GAUGE_PATH: &str = "nrf_fuel_gauge/lib/cortex-m33/hard-float/libnrf_fuel_gauge.a";
fn main() {
use std::env;
use std::path::{Path, PathBuf};
let nrfxlib_path = "./third_party/nordic/nrfxlib";
// Generate bindings with bindgen
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header("wrapper.h")
.parse_callbacks(Box::new(DocCallback))
// Point to Nordic headers
.clang_arg("-I./include")
.clang_arg(format!("-I{}", nrfxlib_path))
.clang_arg(format!("-I{}/crypto/nrf_cc310_platform/include", nrfxlib_path))
.clang_arg(format!("-I{}/crypto/nrf_oberon", nrfxlib_path))
// Disable standard includes (they belong to the host)
.clang_arg("-nostdinc")
.use_core()
.ctypes_prefix("core::ffi")
// Include only the useful stuff
.allowlist_function("nrf_.*")
.allowlist_type("nrf_.*")
.allowlist_var("NRF_.*")
.allowlist_function("ocrypto_.*")
// Format the output
.formatter(bindgen::Formatter::Prettyplease)
// Use signed macro const type
.default_macro_constant_type(bindgen::MacroTypeVariation::Signed)
.generate()
.expect("Unable to generate bindings");
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings.write_to_file(out_path.join("bindings.rs")).expect("Couldn't write bindings!");
// Evaluate which library to use, based on the log feature
let modem_lib: String = if cfg!(feature = "log") {
"modem_log".into()
} else {
"modem".into()
};
let modem_libf = format!("lib{}.a", modem_lib);
let sip = "cellular/nrf9160";
// Copy libraries to the output directory (makes it easier to detect changed library names on future updates)
let libmodem_path = Path::new(&nrfxlib_path).join(format!("nrf_modem/lib/{sip}/hard-float/{modem_libf}"));
let liboberon_path = Path::new(&nrfxlib_path).join(LIBOBERON_PATH);
let libcc310_path = Path::new(&nrfxlib_path).join(LIBCC310_PATH);
let libfuel_gauge_path = Path::new(&nrfxlib_path).join(LIBFUEL_GAUGE_PATH);
std::fs::copy(libmodem_path.clone(), out_path.join(libmodem_path.file_name().unwrap())).unwrap();
std::fs::copy(liboberon_path.clone(), out_path.join(liboberon_path.file_name().unwrap())).unwrap();
std::fs::copy(libcc310_path.clone(), out_path.join(libcc310_path.file_name().unwrap())).unwrap();
std::fs::copy(libfuel_gauge_path.clone(), out_path.join(libfuel_gauge_path.file_name().unwrap())).unwrap();
// Link libraries
println!("cargo:rustc-link-search={}", out_path.display());
println!("cargo:rustc-link-lib=static={}", modem_lib);
println!("cargo:rustc-link-lib=static=nrf_cc310_platform_0.9.19");
println!("cargo:rustc-link-lib=static=oberon_3.0.15");
println!("cargo:rustc-link-lib=static=nrf_fuel_gauge");
}
#[derive(Debug)]
struct DocCallback;
impl bindgen::callbacks::ParseCallbacks for DocCallback {
fn process_comment(&self, comment: &str) -> Option<String> {
let mut comment = comment.to_owned();
// Format inline @brief
let re = regex::Regex::new("\\s*@brief\\s*(?P<msg>.*)").unwrap();
comment = re.replace_all(&comment, "$msg").into();
// Format deprecation notice (@deprecated) as deprecated
let re = regex::Regex::new(r"@deprecated").unwrap();
comment = re
.replace_all(&comment, "**Deprecated**")
.into();
// Format @param as list element
let re = regex::Regex::new(r"\s*@[pP]aram\s*(\[(?P<typ>[\w,\s]+)\s*\])?\s*(\\t)?(?P<var>[\w\.]+)\s+").unwrap();
comment = re.replace_all(&comment, "\n * `$var` $typ - ").into();
// Format @details as a section
let re = regex::Regex::new(r"\s*@details?\s*(?P<var>.*)").unwrap();
comment = re.replace_all(&comment, "\n# Details \n$var").into();
// Format inline @note as bold
let re = regex::Regex::new(r"\s*@note:?\s*").unwrap();
comment = re.replace_all(&comment, "\n\n**Note:** ").into();
// Format references
// $ref, <post> in case of newlines
let re = regex::Regex::new(r"\s*@(ref|refitem)\s+(?P<var>\w+)(\(\))?\.?(?P<post>\s+)").unwrap();
comment = re.replace_all(&comment, " [$var]$post").into();
// NRF_*
let re = regex::Regex::new(r"(?P<pre>\s*)(@[pac])?[\s-]+#?(?P<var>NRF_\w+)(?P<post>\s*)").unwrap();
comment = re.replace_all(&comment, "$pre[$var]$post").into();
// Return values (@retval/@returns/@return)
let re = regex::Regex::new(r"@(returns?|retval)\s+(?P<min>\-?)\s?(?P<var>\[?\w+\]?)").unwrap();
// First entry is header, rest are list items
comment = re.replace(&comment, "\n# Returns\n * $var ").into();
comment = re.replace_all(&comment, "\n * $min$var ").into();
// Format @p/@a/@c arguments as inline code
let re = regex::Regex::new(r"@[pac]\s+(?P<var>[\*A-Za-z0-9_\(\)]+)").unwrap();
comment = re.replace_all(&comment, " `$var` ").into();
Some(comment)
}
}