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"
77license = " Apache 2.0"
88publish = false
99
10+ [build-dependencies ]
11+ bindgen = " 0.60.1"
12+
1013[dependencies ]
1114solana-program = " =1.10.29"
15+ borsh = " 0.9"
16+
1217
1318[lib ]
1419crate-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+
15fn main ( ) {
26 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!" ) ;
326}
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
31mod c_oracle_header;
42mod time_machine_types;
53
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+
621//do not link with C during unit tests (which are built in native architecture, unlike libpyth.o)
722#[ cfg( target_arch = "bpf" ) ]
823#[ link( name = "cpyth" ) ]
Original file line number Diff line number Diff line change @@ -40,8 +40,6 @@ rm ./target/*-keypair.json
4040
4141# build Rust and link it with C
4242cd " ${RUST_DIR} "
43- cargo install bindgen
44- bindgen ./src/bindings.h -o ./src/c_oracle_header.rs
4543cargo clean
4644cargo test
4745cargo clean
You can’t perform that action at this time.
0 commit comments