-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathbuild.rs
169 lines (155 loc) · 6.28 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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//! Build Script for nrfxlib-sys
//!
//! Calls out to bindgen to generate a Rust crate from the Nordic header
//! files.
#[cfg(not(any(
feature = "nrf9160",
feature = "nrf9120",
feature = "nrf9151",
feature = "nrf9161",
)))]
compile_error!(
"No chip feature selected. You must selected exactly one of the following features:
nrf9160,
nrf9151,
nrf9161,
"
);
fn main() {
use std::env;
use std::path::{Path, PathBuf};
let nrfxlib_path = "./third_party/nordic/nrfxlib";
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header("wrapper.h")
// Point to Nordic headers
.clang_arg(format!("-I{}", nrfxlib_path))
// Point to our special local headers
.clang_arg("-I./include")
// Add extra paths that the C files assume are searched
.clang_arg("-I./third_party/nordic/nrfxlib/crypto/nrf_cc310_platform/include")
.clang_arg("-I./third_party/nordic/nrfxlib/crypto/nrf_cc310_mbedcrypto/include")
.clang_arg("-I./third_party/nordic/nrfxlib/crypto/nrf_oberon")
// Disable standard includes (they belong to the host)
.clang_arg("-nostdinc")
// Set the target
.clang_arg("-target")
.clang_arg("arm")
.clang_arg("-mcpu=cortex-m33")
// Use softfp
.clang_arg("-mfloat-abi=soft")
// We're no_std
.use_core()
// Include only the useful stuff
.allowlist_function("nrf_.*")
.allowlist_function("ocrypto_.*")
.allowlist_function("bsd_.*")
.allowlist_type("nrf_.*")
.allowlist_type("ocrypto_.*")
.allowlist_var("NRF_.*")
.allowlist_var("BSD_.*")
.allowlist_var("OCRYPTO_.*")
// Format the output
.formatter(bindgen::Formatter::Rustfmt)
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");
// Write the bindings to the $OUT_DIR/bindings.rs file.
let mut rust_source = bindings.to_string();
// Munge Doxygen comments into something Rustdoc can handle
rust_source = rust_source.replace("#[doc = \"@{*/\"]", "");
let re = regex::Regex::new("\" \\s+- ").unwrap();
rust_source = re.replace_all(&rust_source, "\" * ").into();
let re = regex::Regex::new(r"\s*@param\s+(?P<var>[A-Za-z0-9_]+)\s+").unwrap();
rust_source = re.replace_all(&rust_source, " * `$var` - ").into();
let re =
regex::Regex::new(r"\s*@param\[(out|in|inout|in,out)\](\\t|\s+)(?P<var>[A-Za-z0-9_]+)\s+")
.unwrap();
rust_source = re.replace_all(&rust_source, " * `$var` - ").into();
let re = regex::Regex::new(r"@[cp]\s+(?P<var>[A-Za-z0-9_\(\)]+)").unwrap();
rust_source = re.replace_all(&rust_source, " * `$var` - ").into();
let re = regex::Regex::new(r"\\\\[cp]\s+(?P<var>[A-Za-z0-9_\(\)]+)").unwrap();
rust_source = re.replace_all(&rust_source, "`$var`").into();
let re = regex::Regex::new(r"\\\\ref\s+(?P<var>[A-Za-z0-9_\(\)]+)").unwrap();
rust_source = re.replace_all(&rust_source, "`$var`").into();
rust_source = rust_source.replace("\" @remark", "\" NB: ");
rust_source = rust_source.replace("\"@brief", "\"");
rust_source = rust_source.replace("\" @brief", "\" ");
rust_source = rust_source.replace("\"@detail", "\"");
rust_source = rust_source.replace("\" @detail", "\" ");
rust_source = rust_source.replace("@name ", "# ");
rust_source = rust_source.replace("@return ", "Returns ");
rust_source = rust_source.replace("@retval ", "Returns ");
let bindings_out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs");
std::fs::write(bindings_out_path, rust_source).expect("Couldn't write updated bindgen output");
#[cfg(feature = "nrf9160")]
let libmodem_original_path =
Path::new(&nrfxlib_path).join("nrf_modem/lib/cellular/nrf9160/hard-float/libmodem.a");
#[cfg(feature = "nrf9120")]
let libmodem_original_path =
Path::new(&nrfxlib_path).join("nrf_modem/lib/cellular/nrf9120/hard-float/libmodem.a");
let libmodem_changed_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("libmodem.a");
// The modem library now has compressed headers, but Rust cannot deal with that.
// If the appropriate features is active, we're gonna strip it or decompress it.
#[cfg(feature = "arm-none-eabi-objcopy")]
{
// We assume the arm-none-eabi-objcopy comes from the official arm website.
let child = std::process::Command::new("arm-none-eabi-objcopy")
.arg("--decompress-debug-sections")
.arg(&libmodem_original_path)
.arg(&libmodem_changed_path)
.spawn()
.expect("Could not start `arm-none-eabi-objcopy`. Is it installed and available in your path?");
let child_result = child.wait_with_output().unwrap();
if !child_result.status.success() {
panic!("Something went wrong with `arm-none-eabi-objcopy`.");
}
}
#[cfg(feature = "llvm-objcopy")]
{
// We assume the llvm-objcopy comes from the rustup llvm-tools.
// This cannot do decompression, so we'll just strip the debug sections
let tool_error = "Could not find `llvm-objcopy`. Is it installed? Use `rustup component add llvm-tools` to install it or select the `arm-none-eabi-objcopy` feature if you have that tool installed.";
// It's not in our path, so we have to search for it
let path = llvm_tools::LlvmTools::new()
.expect(tool_error)
.tool(&llvm_tools::exe("llvm-objcopy"))
.expect(tool_error);
let child = std::process::Command::new(path)
.arg("--strip-debug")
.arg(&libmodem_original_path)
.arg(&libmodem_changed_path)
.spawn()
.expect(tool_error);
let child_result = child.wait_with_output().unwrap();
if !child_result.status.success() {
panic!("Something went wrong with `llvm-objcopy`.");
}
}
// Make sure we link against the libraries
println!(
"cargo:rustc-link-search={}",
libmodem_changed_path.parent().unwrap().display()
);
println!(
"cargo:rustc-link-search={}",
Path::new(&nrfxlib_path)
.join("crypto/nrf_oberon/lib/cortex-m33/hard-float")
.display()
);
// the no interrupt version of the library does not use mutexes, it is easier to handle
println!(
"cargo:rustc-link-search={}",
Path::new(&nrfxlib_path)
.join("crypto/nrf_cc310_platform/lib/cortex-m33/hard-float/no-interrupts")
.display()
);
println!("cargo:rustc-link-lib=static=modem");
println!("cargo:rustc-link-lib=static=oberon_3.0.15");
println!("cargo:rustc-link-lib=static=nrf_cc310_platform_0.9.19");
}