Skip to content

Commit c817c42

Browse files
committed
rust: Allow cargo to create c libs as needed for tests
1 parent 22075a4 commit c817c42

File tree

4 files changed

+78
-32
lines changed

4 files changed

+78
-32
lines changed

src/rust/bitbox02-sys/Cargo.toml

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

2323
[dependencies]
2424
util = {path = "../util"}
25+
26+
[features]
27+
testing = []

src/rust/bitbox02-sys/build.rs

+74-5
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,32 @@ fn main() {
77
// if we are being invoked from CMAKE, the bindings are here:
88
format!("{}/rust", cmake_dir)
99
} else {
10+
// Else we generate the list ourselves.
11+
//
12+
// For this to work you'll need to be able to call "make rust-bindgen-includes" on your
13+
// developer machine. We aren't using docker here because we don't really need that many
14+
// tools for this to work.
15+
//
16+
// In the best of worlds we would have a "rerun-if-changed=<all necessary c headers>"
17+
1018
let bitbox02_sys_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
1119
let cmake_dir = format!("{}/../../../", bitbox02_sys_dir);
1220
let outdir = std::env::var("OUT_DIR").unwrap();
1321

14-
// generate list of includes using CMake
1522
let cmake_builddir = format!("{}/_cmake_build_dir", outdir);
1623
std::fs::create_dir_all(&cmake_builddir).expect("failed to create a directory");
1724
let out = Command::new("cmake").arg(&cmake_dir).current_dir(&cmake_builddir).output().unwrap();
18-
assert!(out.status.success());
25+
if !out.status.success() {
26+
println!("{}", std::str::from_utf8(&out.stdout).unwrap());
27+
println!("{}", std::str::from_utf8(&out.stderr).unwrap());
28+
panic!()
29+
}
1930
let out = Command::new("make").arg("rust-bindgen-includes").current_dir(&cmake_builddir).output().unwrap();
20-
println!("{}", std::str::from_utf8(&out.stdout).unwrap());
21-
println!("{}", std::str::from_utf8(&out.stderr).unwrap());
22-
assert!(out.status.success());
31+
if !out.status.success() {
32+
println!("{}", std::str::from_utf8(&out.stdout).unwrap());
33+
println!("{}", std::str::from_utf8(&out.stderr).unwrap());
34+
panic!()
35+
}
2336
let mut includes_file = File::open(format!("{}/src/rust-bindgen.flags", cmake_builddir)).unwrap();
2437
let mut includes = String::new();
2538
includes_file.read_to_string(&mut includes).unwrap();
@@ -41,4 +54,60 @@ fn main() {
4154
outdir
4255
};
4356
println!("cargo:rustc-env=BINDINGS={}/bindings.rs", path_to_bindings);
57+
58+
// If we are testing we have to build a special library called "bitbox_merged" that contain
59+
// both all C code and rust code. So that rust -> c -> rust interop works.
60+
//
61+
// For this to work you'll need the most recent docker container setup. You also probably need
62+
// to use the same version of the rust and c compiler on your machine as in the container.
63+
#[cfg(feature = "testing")]
64+
{
65+
use std::path::PathBuf;
66+
67+
let cmake_builddir = if let Ok(cmake_builddir) = std::env::var("CMAKE_CURRENT_BINARY_DIR") {
68+
String::from(cmake_builddir.strip_suffix("/src").unwrap())
69+
} else {
70+
let bitbox02_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
71+
let cmake_dir = format!("{}/../../../", bitbox02_dir);
72+
let outdir = std::env::var("OUT_DIR").unwrap();
73+
let cmake_builddir = format!("{}/_cmake_build_dir_docker", outdir);
74+
let docker_exec = "../../../scripts/docker_exec.sh";
75+
std::fs::create_dir_all(&cmake_builddir).expect("failed to create a directory");
76+
// paths are relative to _inside_ docker container
77+
let cmake_dir_pathbuf = String::from(PathBuf::from(cmake_dir).canonicalize().unwrap().to_str().unwrap());
78+
let outdir_in_docker = outdir.strip_prefix(&cmake_dir_pathbuf).unwrap().strip_prefix('/').unwrap();
79+
let cmake_builddir_in_docker = format!("{}/_cmake_build_dir_docker", outdir_in_docker);
80+
println!("{}", cmake_builddir_in_docker);
81+
let chdir_and_run = format!("cd {} && cmake ../../../../../../../../", cmake_builddir_in_docker);
82+
let out = Command::new(&docker_exec).arg(&chdir_and_run).output().unwrap();
83+
if !out.status.success() {
84+
println!("{}", std::str::from_utf8(&out.stdout).unwrap());
85+
println!("{}", std::str::from_utf8(&out.stderr).unwrap());
86+
panic!()
87+
}
88+
let chdir_and_run = format!("make -C {} bitbox_merged", cmake_builddir_in_docker);
89+
let out = Command::new(&docker_exec).arg(&chdir_and_run).output().unwrap();
90+
if !out.status.success() {
91+
println!("{}", std::str::from_utf8(&out.stdout).unwrap());
92+
println!("{}", std::str::from_utf8(&out.stderr).unwrap());
93+
panic!()
94+
}
95+
cmake_builddir
96+
};
97+
println!("cargo:rustc-link-search={}/lib", cmake_builddir);
98+
// c and rust code merged :O
99+
println!("cargo:rustc-link-lib=bitbox_merged");
100+
101+
// external libs
102+
println!("cargo:rustc-link-lib=wallycore");
103+
println!("cargo:rustc-link-lib=secp256k1");
104+
println!("cargo:rustc-link-lib=base32");
105+
println!("cargo:rustc-link-lib=ctaes");
106+
println!("cargo:rustc-link-lib=fatfs");
107+
println!("cargo:rustc-link-lib=sd-mock");
108+
109+
// system libs
110+
println!("cargo:rustc-link-lib=cmocka");
111+
}
112+
44113
}

src/rust/bitbox02/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ lazy_static = { version = "1.4.0", optional = true }
2828

2929
[features]
3030
# Only to be enabled in unit tests.
31-
testing = ["lazy_static"]
31+
testing = ["lazy_static", "bitbox02-sys/testing"]
3232

3333
app-ethereum = []
3434
app-bitcoin = []

src/rust/bitbox02/build.rs

-26
This file was deleted.

0 commit comments

Comments
 (0)