@@ -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 ( ) == false {
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 ( ) == false {
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 = format ! ( "../../../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 ( ) == false {
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 ( ) == false {
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}
0 commit comments