11extern crate bindgen;
22
3+ use regex:: Regex ;
34use std:: env;
4- use std:: io:: { self , Result } ;
5+ use std:: fs;
6+ use std:: io:: { self , Read , Result } ;
57use std:: path:: PathBuf ;
68
79/// Perform crate build.
@@ -18,9 +20,26 @@ fn main() {
1820fn run_build ( ) -> Result < ( ) > {
1921 generate_bindings ( ) ?;
2022 setup_wolfssl_link ( ) ?;
23+ scan_cfg ( ) ?;
2124 Ok ( ( ) )
2225}
2326
27+ fn wrapper_dir ( ) -> Result < String > {
28+ Ok ( std:: env:: current_dir ( ) ?. display ( ) . to_string ( ) )
29+ }
30+
31+ fn wolfssl_base_dir ( ) -> Result < String > {
32+ Ok ( format ! ( "{}/../../.." , wrapper_dir( ) ?) )
33+ }
34+
35+ fn wolfssl_lib_dir ( ) -> Result < String > {
36+ Ok ( format ! ( "{}/src/.libs" , wolfssl_base_dir( ) ?) )
37+ }
38+
39+ fn bindings_path ( ) -> String {
40+ PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) . join ( "bindings.rs" ) . display ( ) . to_string ( )
41+ }
42+
2443/// Generate Rust bindings for the wolfssl C library using bindgen.
2544///
2645/// This function:
@@ -31,19 +50,15 @@ fn run_build() -> Result<()> {
3150///
3251/// Returns `Ok(())` if successful, or an error if binding generation fails.
3352fn generate_bindings ( ) -> Result < ( ) > {
34- let wrapper_dir = std:: env:: current_dir ( ) ?. display ( ) . to_string ( ) ;
35- let wolfssl_base_dir = format ! ( "{}/../../.." , wrapper_dir) ;
36-
3753 let bindings = bindgen:: Builder :: default ( )
3854 . header ( "headers.h" )
39- . clang_arg ( format ! ( "-I{}" , wolfssl_base_dir) )
55+ . clang_arg ( format ! ( "-I{}" , wolfssl_base_dir( ) ? ) )
4056 . parse_callbacks ( Box :: new ( bindgen:: CargoCallbacks :: new ( ) ) )
4157 . generate ( )
4258 . map_err ( |_| io:: Error :: new ( io:: ErrorKind :: Other , "Failed to generate bindings" ) ) ?;
4359
44- let out_path = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ;
4560 bindings
46- . write_to_file ( out_path . join ( "bindings.rs" ) )
61+ . write_to_file ( bindings_path ( ) )
4762 . map_err ( |e| {
4863 io:: Error :: new (
4964 io:: ErrorKind :: Other ,
@@ -56,16 +71,112 @@ fn generate_bindings() -> Result<()> {
5671///
5772/// Returns `Ok(())` if successful, or an error if any step fails.
5873fn setup_wolfssl_link ( ) -> Result < ( ) > {
59- let wrapper_dir = std:: env:: current_dir ( ) ?. display ( ) . to_string ( ) ;
60- let wolfssl_base_dir = format ! ( "{}/../../.." , wrapper_dir) ;
61- let wolfssl_lib_dir = format ! ( "{}/src/.libs" , wolfssl_base_dir) ;
62-
63- println ! ( "cargo:rustc-link-search={}" , wolfssl_lib_dir) ;
6474 println ! ( "cargo:rustc-link-lib=wolfssl" ) ;
65- println ! ( "cargo:rustc-link-arg=-Wl,-rpath,{}" , wolfssl_lib_dir) ;
75+ println ! ( "cargo:rustc-link-search={}" , wolfssl_lib_dir( ) ?) ;
76+ println ! ( "cargo:rustc-link-arg=-Wl,-rpath,{}" , wolfssl_lib_dir( ) ?) ;
6677
6778// TODO: do we need this if only a static library is built?
6879// println!("cargo:rustc-link-lib=static=wolfssl");
6980
7081 Ok ( ( ) )
7182}
83+
84+ fn read_file ( path : String ) -> Result < String > {
85+ let mut file = fs:: File :: open ( path) ?;
86+ let mut content = String :: new ( ) ;
87+ file. read_to_string ( & mut content) ?;
88+ Ok ( content)
89+ }
90+
91+ fn check_cfg ( binding : & str , function_name : & str , cfg_name : & str ) {
92+ let pattern = format ! ( r"\b{}\b" , function_name) ;
93+ let re = match Regex :: new ( & pattern) {
94+ Ok ( r) => r,
95+ Err ( e) => {
96+ eprintln ! ( "Error compiling regex '{}': {}" , pattern, e) ;
97+ return ;
98+ }
99+ } ;
100+ println ! ( "cargo::rustc-check-cfg=cfg({})" , cfg_name) ;
101+ if re. is_match ( binding) {
102+ println ! ( "cargo:rustc-cfg={}" , cfg_name) ;
103+ }
104+ }
105+
106+ fn scan_cfg ( ) -> Result < ( ) > {
107+ let binding = read_file ( bindings_path ( ) ) ?;
108+
109+ /* aes */
110+ check_cfg ( & binding, "wc_AesSetKey" , "aes" ) ;
111+ check_cfg ( & binding, "wc_AesCbcEncrypt" , "aes_cbc" ) ;
112+ check_cfg ( & binding, "wc_AesCcmSetKey" , "aes_ccm" ) ;
113+ check_cfg ( & binding, "wc_AesCfbEncrypt" , "aes_cfb" ) ;
114+ check_cfg ( & binding, "wc_AesCtrEncrypt" , "aes_ctr" ) ;
115+ check_cfg ( & binding, "wc_AesCtsEncrypt" , "aes_cts" ) ;
116+ check_cfg ( & binding, "wc_AesCfbDecrypt" , "aes_decrypt" ) ;
117+ check_cfg ( & binding, "wc_AesEaxInit" , "aes_eax" ) ;
118+ check_cfg ( & binding, "wc_AesEcbEncrypt" , "aes_ecb" ) ;
119+ check_cfg ( & binding, "wc_AesGcmSetKey" , "aes_gcm" ) ;
120+ check_cfg ( & binding, "wc_AesGcmInit" , "aes_gcm_stream" ) ;
121+ check_cfg ( & binding, "wc_AesOfbEncrypt" , "aes_ofb" ) ;
122+ check_cfg ( & binding, "wc_AesXtsInit" , "aes_xts" ) ;
123+ check_cfg ( & binding, "wc_AesXtsEncryptInit" , "aes_xts_stream" ) ;
124+
125+ /* cmac */
126+ check_cfg ( & binding, "wc_InitCmac" , "cmac" ) ;
127+
128+ /* dh */
129+ check_cfg ( & binding, "wc_InitDhKey" , "dh" ) ;
130+ check_cfg ( & binding, "wc_DhGenerateParams" , "dh_keygen" ) ;
131+
132+ /* ecc */
133+ check_cfg ( & binding, "wc_ecc_init" , "ecc" ) ;
134+ check_cfg ( & binding, "wc_ecc_export_point_der_compressed" , "ecc_comp_key" ) ;
135+ check_cfg ( & binding, "wc_ecc_shared_secret" , "ecc_dh" ) ;
136+ check_cfg ( & binding, "wc_ecc_sign_hash" , "ecc_sign" ) ;
137+ check_cfg ( & binding, "wc_ecc_verify_hash" , "ecc_verify" ) ;
138+ check_cfg ( & binding, "wc_ecc_export_x963" , "ecc_export" ) ;
139+ check_cfg ( & binding, "wc_ecc_import_x963" , "ecc_import" ) ;
140+ check_cfg ( & binding, "ecc_curve_ids_ECC_X25519" , "ecc_curve_25519" ) ;
141+ check_cfg ( & binding, "ecc_curve_ids_ECC_X448" , "ecc_curve_448" ) ;
142+ check_cfg ( & binding, "ecc_curve_ids_ECC_SAKKE_1" , "ecc_curve_sakke" ) ;
143+ check_cfg ( & binding, "ecc_curve_ids_ECC_CURVE_CUSTOM" , "ecc_custom_curves" ) ;
144+
145+ /* ed25519 */
146+ check_cfg ( & binding, "wc_ed25519_init" , "ed25519" ) ;
147+ check_cfg ( & binding, "wc_ed25519_import_public" , "ed25519_import" ) ;
148+ check_cfg ( & binding, "wc_ed25519_export_public" , "ed25519_export" ) ;
149+ check_cfg ( & binding, "wc_ed25519_sign_msg" , "ed25519_sign" ) ;
150+ check_cfg ( & binding, "wc_ed25519_verify_msg_ex" , "ed25519_verify" ) ;
151+ check_cfg ( & binding, "wc_ed25519_verify_msg_init" , "ed25519_streaming_verify" ) ;
152+
153+ /* ed448 */
154+ check_cfg ( & binding, "wc_ed448_init" , "ed448" ) ;
155+ check_cfg ( & binding, "wc_ed448_import_public" , "ed448_import" ) ;
156+ check_cfg ( & binding, "wc_ed448_export_public" , "ed448_export" ) ;
157+ check_cfg ( & binding, "wc_ed448_sign_msg" , "ed448_sign" ) ;
158+ check_cfg ( & binding, "wc_ed448_verify_msg_ex" , "ed448_verify" ) ;
159+ check_cfg ( & binding, "wc_ed448_verify_msg_init" , "ed448_streaming_verify" ) ;
160+
161+ /* kdf */
162+ check_cfg ( & binding, "wc_PBKDF2" , "kdf_pbkdf2" ) ;
163+ check_cfg ( & binding, "wc_PKCS12_PBKDF_ex" , "kdf_pkcs12" ) ;
164+ check_cfg ( & binding, "wc_SRTP_KDF" , "kdf_srtp" ) ;
165+ check_cfg ( & binding, "wc_SSH_KDF" , "kdf_ssh" ) ;
166+ check_cfg ( & binding, "wc_Tls13_HKDF_Extract_ex" , "kdf_tls13" ) ;
167+
168+ /* rsa */
169+ check_cfg ( & binding, "wc_InitRsaKey" , "rsa" ) ;
170+ check_cfg ( & binding, "wc_RsaDirect" , "rsa_direct" ) ;
171+ check_cfg ( & binding, "wc_MakeRsaKey" , "rsa_keygen" ) ;
172+
173+ /* sha */
174+ check_cfg ( & binding, "wc_InitSha" , "sha" ) ;
175+ check_cfg ( & binding, "wc_InitSha256" , "sha256" ) ;
176+ check_cfg ( & binding, "wc_InitSha512" , "sha512" ) ;
177+ check_cfg ( & binding, "wc_InitSha3_224" , "sha3" ) ;
178+ check_cfg ( & binding, "wc_InitShake128" , "shake128" ) ;
179+ check_cfg ( & binding, "wc_InitShake256" , "shake256" ) ;
180+
181+ Ok ( ( ) )
182+ }
0 commit comments