Skip to content

Commit c60907b

Browse files
committed
rust: enable bindings to be built without existing cmake build dir
1 parent 53380d6 commit c60907b

File tree

14 files changed

+764
-23
lines changed

14 files changed

+764
-23
lines changed

.gitattributes

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
/py/bitbox02/bitbox02/generated/* linguist-generated=true
1+
/py/bitbox02/bitbox02/generated/** linguist-generated=true
2+
/src/rust/vendor/** linguist-generated=true

src/CMakeLists.txt

+8
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,14 @@ add_custom_target(rust-bindgen
306306
)
307307
add_dependencies(rust-bindgen generate-protobufs)
308308

309+
# A custom target to export the list of includes for rust tooling (RA, clippy)
310+
add_custom_command(OUTPUT rust-bindgen.flags
311+
COMMAND
312+
${CMAKE_COMMAND} -E echo ${RUST_INCLUDES} > rust-bindgen.flags
313+
)
314+
add_custom_target(rust-bindgen-includes DEPENDS rust-bindgen.flags)
315+
add_dependencies(rust-bindgen-includes generate-protobufs)
316+
309317

310318
# Test rust crates that contain business logic. Avoid testing crates that depend on hardware.
311319
if(NOT CMAKE_CROSSCOMPILING)

src/rust/Cargo.lock

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rust/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,9 @@ The bottom-most layer are bindings generated from C header files:
3535

3636
We generate one header file `rust.h` and ever product specific function is `#ifdeffed` with
3737
`RUST_PRODUCT_*` macro.
38+
39+
40+
# rust-analyzer / clippy
41+
42+
To be able to run static analyzers you'll need nanopb to work and libclang to be available on the
43+
host machine.

src/rust/bitbox02-sys/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ license = "Apache-2.0"
2222

2323
[dependencies]
2424
util = {path = "../util"}
25+
26+
[build-dependencies]
27+
# We chose leonard-llc/temp-dir over rust-lang/tempdir because it has fewer dependencies
28+
temp-dir = "0.1"

src/rust/bitbox02-sys/build.rs

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use std::process::Command;
2+
use std::fs::File;
3+
use std::io::prelude::*;
4+
use temp_dir::TempDir;
5+
6+
fn main() {
7+
let path_to_bindings = if let Ok(cmake_dir) = std::env::var("CMAKE_CURRENT_BINARY_DIR") {
8+
// if we are being invoked from CMAKE, the bindings are here:
9+
format!("{}/rust", cmake_dir)
10+
} else {
11+
let bitbox02_sys_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
12+
let cmake_dir = format!("{}/../../../", bitbox02_sys_dir);
13+
14+
// generate list of includes using CMake
15+
let tempdir = TempDir::with_prefix("bitbox02").unwrap();
16+
let tempdir = tempdir.path().to_str().unwrap();
17+
let _ = Command::new("cmake").arg(&cmake_dir).current_dir(&tempdir).output().unwrap();
18+
let _ = Command::new("make").arg("rust-bindgen-includes").current_dir(&tempdir).output().unwrap();
19+
let mut includes_file = File::open(format!("{}/src/rust-bindgen.flags", tempdir)).unwrap();
20+
let mut includes = String::new();
21+
includes_file.read_to_string(&mut includes).unwrap();
22+
let includes:Vec<&str> = includes.trim().split_ascii_whitespace().collect();
23+
let target = std::env::var("TARGET").unwrap();
24+
let mut flags = vec!["-target", &target, "-DTESTING=1"];
25+
flags.extend(&includes);
26+
27+
// generate bindings
28+
let outdir = std::env::var("OUT_DIR").unwrap();
29+
let generate_bindings = format!("{}/scripts/generate-bindings.sh", cmake_dir);
30+
let bindings = format!("{}/bindings.rs", outdir);
31+
let wrapper = format!("{}/wrapper.h", bitbox02_sys_dir);
32+
let _ = Command::new(&generate_bindings)
33+
.args(&[&bindings, &wrapper])
34+
.args(&flags)
35+
.output()
36+
.unwrap();
37+
38+
outdir
39+
};
40+
println!("cargo:rustc-env=BINDINGS={}/bindings.rs", path_to_bindings);
41+
}

src/rust/bitbox02-sys/src/lib.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@
1717
#![allow(non_upper_case_globals)]
1818
#![allow(non_camel_case_types)]
1919
#![allow(non_snake_case)]
20+
#![allow(clippy::all)]
2021

2122
// include our generated bindings
22-
include!(concat!(
23-
env!("CMAKE_CURRENT_BINARY_DIR"),
24-
"/rust",
25-
"/bindings.rs"
26-
));
23+
include!(env!("BINDINGS"));

src/rust/bitbox02/build.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
fn main() {
22
#[cfg(feature = "testing")]
33
{
4-
let cmake_dir = std::env::var("CMAKE_CURRENT_BINARY_DIR").unwrap();
5-
println!("cargo:rustc-link-search={}/../lib", cmake_dir);
6-
// c and rust code merged :O
7-
println!("cargo:rustc-link-lib=bitbox_merged");
8-
println!(
9-
"cargo:rerun-if-changed={}/../lib/libbitbox_merged.a",
10-
cmake_dir
11-
);
4+
// CMAKE_CURRENT_BINARY_DIR is required for building tests
5+
if let Ok(cmake_dir) = std::env::var("CMAKE_CURRENT_BINARY_DIR") {
6+
println!("cargo:rustc-link-search={}/../lib", cmake_dir);
7+
// c and rust code merged :O
8+
println!("cargo:rustc-link-lib=bitbox_merged");
9+
println!(
10+
"cargo:rerun-if-changed={}/../lib/libbitbox_merged.a",
11+
cmake_dir
12+
);
1213

13-
// external libs
14-
println!("cargo:rustc-link-lib=wallycore");
15-
println!("cargo:rustc-link-lib=secp256k1");
16-
println!("cargo:rustc-link-lib=base32");
17-
println!("cargo:rustc-link-lib=ctaes");
18-
println!("cargo:rustc-link-lib=fatfs");
19-
println!("cargo:rustc-link-lib=sd-mock");
14+
// external libs
15+
println!("cargo:rustc-link-lib=wallycore");
16+
println!("cargo:rustc-link-lib=secp256k1");
17+
println!("cargo:rustc-link-lib=base32");
18+
println!("cargo:rustc-link-lib=ctaes");
19+
println!("cargo:rustc-link-lib=fatfs");
20+
println!("cargo:rustc-link-lib=sd-mock");
2021

21-
// system libs
22-
println!("cargo:rustc-link-lib=cmocka");
22+
// system libs
23+
println!("cargo:rustc-link-lib=cmocka");
24+
}
2325
}
2426
}

src/rust/vendor/temp-dir/.cargo-checksum.json

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rust/vendor/temp-dir/Cargo.toml

+27
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rust/vendor/temp-dir/LICENSE

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rust/vendor/temp-dir/Readme.md

+120
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)