File tree Expand file tree Collapse file tree 6 files changed +91
-4
lines changed Expand file tree Collapse file tree 6 files changed +91
-4
lines changed Original file line number Diff line number Diff line change @@ -7,8 +7,13 @@ edition = "2021"
7
7
license = " Apache 2.0"
8
8
publish = false
9
9
10
+ [build-dependencies ]
11
+ bindgen = " 0.60.1"
12
+
10
13
[dependencies ]
11
14
solana-program = " =1.10.29"
15
+ borsh = " 0.9"
16
+
12
17
13
18
[lib ]
14
19
crate-type = [" cdylib" , " lib" ]
Original file line number Diff line number Diff line change
1
+ mod build_utils;
2
+ use bindgen:: Builder ;
3
+ use std:: vec:: Vec ;
4
+
1
5
fn main ( ) {
2
6
println ! ( "cargo:rustc-link-search=../c/target" ) ;
7
+
8
+ let borsh_derives = [ "BorshSerialize" . to_string ( ) , "BorshDeserialize" . to_string ( ) ] ;
9
+
10
+ //make a parser and to it type, traits pairs
11
+ let mut parser = build_utils:: DeriveAdderParserCallback :: new ( ) ;
12
+ parser. register_traits ( "cmd_hdr" , borsh_derives. to_vec ( ) ) ;
13
+ parser. register_traits ( "pc_acc" , borsh_derives. to_vec ( ) ) ;
14
+
15
+
16
+ //generate and write bindings
17
+ let bindings = Builder :: default ( )
18
+ . header ( "./src/bindings.h" )
19
+ . parse_callbacks ( Box :: new ( parser) )
20
+ . rustfmt_bindings ( true )
21
+ . generate ( )
22
+ . expect ( "Unable to generate bindings" ) ;
23
+ bindings
24
+ . write_to_file ( "./bindings.rs" )
25
+ . expect ( "Couldn't write bindings!" ) ;
3
26
}
Original file line number Diff line number Diff line change
1
+ use bindgen:: callbacks:: ParseCallbacks ;
2
+ use std:: collections:: HashMap ;
3
+ use std:: panic:: UnwindSafe ;
4
+ ///This type stores a hashmap from structnames
5
+ ///to vectors of trait names, and ensures
6
+ ///that the traits of each struct are added to its
7
+ ///definition when an instance of this struct
8
+ ///is provided as a ParseCallback for bindgen
9
+ #[ derive( Debug , Default ) ]
10
+ pub struct DeriveAdderParserCallback < ' a > {
11
+ pub types_to_traits : HashMap < & ' a str , Vec < String > > ,
12
+ }
13
+
14
+ impl < ' a > DeriveAdderParserCallback < ' a > {
15
+ ///create a parser that does not add any traits
16
+ pub fn new ( ) -> Self {
17
+ Default :: default ( )
18
+ }
19
+ //add pairs of types and their desired traits
20
+ pub fn register_traits ( & mut self , type_name : & ' a str , traits : Vec < String > ) {
21
+ self . types_to_traits . insert ( & type_name, traits) ;
22
+ }
23
+ }
24
+
25
+ //this is required to implement the callback trait
26
+ impl UnwindSafe for DeriveAdderParserCallback < ' _ > { }
27
+
28
+ impl ParseCallbacks for DeriveAdderParserCallback < ' _ > {
29
+ fn add_derives ( & self , _name : & str ) -> Vec < String > {
30
+ self . types_to_traits
31
+ . get ( _name)
32
+ . unwrap_or ( & Vec :: < String > :: new ( ) )
33
+ . to_vec ( )
34
+ }
35
+ }
Original file line number Diff line number Diff line change
1
+ #![ allow( non_upper_case_globals) ]
2
+ #![ allow( non_camel_case_types) ]
3
+ #![ allow( non_snake_case) ]
4
+ //we do not use all the variables in oracle.h, so this helps with the warnings
5
+ #![ allow( unused_variables) ]
6
+ #![ allow( dead_code) ]
7
+ //All the custom trait imports should go here
8
+ use borsh:: { BorshDeserialize , BorshSerialize } ;
9
+ //bindings.rs is generated by build.rs to include
10
+ //things defined in bindings.h
11
+ include ! ( "../bindings.rs" ) ;
Original file line number Diff line number Diff line change 1
- //c_oracle_header is auto generated by build_bpf.sh
2
- //to reflect the current status of oracle.h
3
1
mod c_oracle_header;
4
2
mod time_machine_types;
5
3
4
+ //Below is a high lever description of the rust/c setup.
5
+
6
+ //As we migrate from C to Rust, our Rust code needs to be able to interract with C
7
+ //build-bpf.sh is set up to compile the C code into a bpf archive file, that build.rs
8
+ //is set up to link the rust targets to. This enables to interact with the c_entrypoint
9
+ //as well as similarly declare other C functions in Rust and call them
10
+
11
+ //We also generate bindings for the types and constants in oracle.h (as well as other things
12
+ //included in bindings.h), these bindings can be accessed through c_oracle_header.rs
13
+ //Bindings allow us to access type definitions, function definitions and constants. In order to
14
+ //add traits to the bindings, we use the parser in build.rs. The traits must be defined/included
15
+ //at the the top of c_oracle_headers.rs. One of the most important traits we deal are the Borsh
16
+ //serialization traits.
17
+
18
+ //the only limitation of our set up is that we can not unit test in rust, anything that calls
19
+ //a c function. Though we can test functions that use constants/types defined in oracle.h
20
+
6
21
//do not link with C during unit tests (which are built in native architecture, unlike libpyth.o)
7
22
#[ cfg( target_arch = "bpf" ) ]
8
23
#[ link( name = "cpyth" ) ]
Original file line number Diff line number Diff line change @@ -40,8 +40,6 @@ rm ./target/*-keypair.json
40
40
41
41
# build Rust and link it with C
42
42
cd " ${RUST_DIR} "
43
- cargo install bindgen
44
- bindgen ./src/bindings.h -o ./src/c_oracle_header.rs
45
43
cargo clean
46
44
cargo test
47
45
cargo clean
You can’t perform that action at this time.
0 commit comments