@@ -66,6 +66,73 @@ mod common {
6666 use std:: io:: { Error , ErrorKind , Result } ;
6767 use std:: path:: { Path , PathBuf } ;
6868
69+ #[ cfg( any( feature = "prefix" , feature = "operations" ) ) ]
70+ pub fn get_external_mbedtls ( ) -> Option < Result < ( String , String ) > > {
71+ if env:: var ( "MBEDTLS_LIB_DIR" ) . is_err ( ) ^ env:: var ( "MBEDTLS_INCLUDE_DIR" ) . is_err ( ) {
72+ return Some ( Err ( Error :: new (
73+ ErrorKind :: Other ,
74+ "both environment variables MBEDTLS_LIB_DIR and MBEDTLS_INCLUDE_DIR need to be set for operations feature" ,
75+ ) ) ) ;
76+ }
77+
78+ if let ( Ok ( lib_dir) , Ok ( include_dir) ) =
79+ ( env:: var ( "MBEDTLS_LIB_DIR" ) , env:: var ( "MBEDTLS_INCLUDE_DIR" ) )
80+ {
81+ println ! ( "Found environment variables, using external MbedTLS" ) ;
82+ return Some ( Ok ( ( include_dir, lib_dir) ) ) ;
83+ }
84+
85+ if let Ok ( mbedtls_result) = pkg_config:: Config :: new ( )
86+ . range_version ( "3.5" .."4.0" )
87+ . probe ( "mbedtls" )
88+ {
89+ let include_dirs: Vec < String > = mbedtls_result
90+ . include_paths
91+ . into_iter ( )
92+ . map ( |x : PathBuf | -> String { x. into_os_string ( ) . into_string ( ) . unwrap ( ) } )
93+ . collect ( ) ;
94+ let include_dir = include_dirs. join ( " " ) ;
95+ // The current build framework doesn't support multiple lib paths for -L unfortuantely, so
96+ // we just take the first element, which is enough for now :-(
97+ let lib_dir = <PathBuf as Clone >:: clone ( & mbedtls_result. link_paths [ 0 ] )
98+ . into_os_string ( )
99+ . into_string ( )
100+ . unwrap ( ) ;
101+ println ! ( "Found pkg-config mbedtls, using external MbedTLS" ) ;
102+ return Some ( Ok ( ( include_dir, lib_dir) ) ) ;
103+ }
104+
105+ // No env vars set and no discovered package through pkg-config
106+ None
107+ }
108+
109+ #[ cfg( all( feature = "interface" , not( feature = "operations" ) ) ) ]
110+ pub fn get_external_mbedtls_include_only ( ) -> Result < String > {
111+ if let Ok ( include_dir) = env:: var ( "MBEDTLS_INCLUDE_DIR" ) {
112+ println ! ( "Found environment variable, using external MbedTLS" ) ;
113+ return Ok ( include_dir) ;
114+ }
115+
116+ if let Ok ( mbedtls_result) = pkg_config:: Config :: new ( )
117+ . range_version ( "3.5" .."4.0" )
118+ . probe ( "mbedtls" )
119+ {
120+ let include_dirs: Vec < String > = mbedtls_result
121+ . include_paths
122+ . into_iter ( )
123+ . map ( |x : PathBuf | -> String { x. into_os_string ( ) . into_string ( ) . unwrap ( ) } )
124+ . collect ( ) ;
125+ let include_dir = include_dirs. join ( " " ) ;
126+
127+ return Ok ( include_dir) ;
128+ }
129+
130+ Err ( Error :: new (
131+ ErrorKind :: Other ,
132+ "interface feature necessitates MBEDTLS_INCLUDE_DIR environment variable" ,
133+ ) )
134+ }
135+
69136 pub fn configure_mbed_crypto ( ) -> Result < ( ) > {
70137 let mbedtls_dir = String :: from ( "./vendor" ) ;
71138 let mbedtls_config = mbedtls_dir + "/scripts/config.py" ;
@@ -209,22 +276,17 @@ mod common {
209276#[ cfg( all( feature = "interface" , not( feature = "operations" ) ) ) ]
210277mod interface {
211278 use super :: common;
212- use std:: env;
213- use std:: io:: { Error , ErrorKind , Result } ;
279+ use std:: io:: Result ;
214280
215281 // Build script when the interface feature is on and not the operations one
216282 pub fn script_interface ( ) -> Result < ( ) > {
217- if let Ok ( include_dir) = env:: var ( "MBEDTLS_INCLUDE_DIR" ) {
218- common:: configure_mbed_crypto ( ) ?;
219- common:: generate_mbed_crypto_bindings ( include_dir. clone ( ) , false ) ?;
220- let _ = common:: compile_shim_library ( include_dir, true , false ) ?;
221- Ok ( ( ) )
222- } else {
223- Err ( Error :: new (
224- ErrorKind :: Other ,
225- "interface feature necessitates MBEDTLS_INCLUDE_DIR environment variable" ,
226- ) )
227- }
283+ let include_dir = common:: get_external_mbedtls_include_only ( ) ?;
284+
285+ // TODO: Does interface need the vendored mbedtls?
286+ common:: configure_mbed_crypto ( ) ?;
287+ common:: generate_mbed_crypto_bindings ( include_dir. clone ( ) , false ) ?;
288+ let _ = common:: compile_shim_library ( include_dir, true , false ) ?;
289+ Ok ( ( ) )
228290 }
229291}
230292
@@ -235,9 +297,9 @@ mod operations {
235297 use super :: common:: prefix;
236298 use cmake:: Config ;
237299 use std:: env;
300+ use std:: io:: Result ;
238301 #[ cfg( feature = "prefix" ) ]
239302 use std:: io:: Write ;
240- use std:: io:: { Error , ErrorKind , Result } ;
241303 use std:: path:: PathBuf ;
242304 use walkdir:: WalkDir ;
243305
@@ -288,36 +350,31 @@ mod operations {
288350 let include;
289351 let external_mbedtls;
290352
291- if env:: var ( "MBEDTLS_LIB_DIR" ) . is_err ( ) ^ env:: var ( "MBEDTLS_INCLUDE_DIR" ) . is_err ( ) {
292- return Err ( Error :: new (
293- ErrorKind :: Other ,
294- "both environment variables MBEDTLS_LIB_DIR and MBEDTLS_INCLUDE_DIR need to be set for operations feature" ,
295- ) ) ;
296- }
297- if let ( Ok ( lib_dir) , Ok ( include_dir) ) =
298- ( env:: var ( "MBEDTLS_LIB_DIR" ) , env:: var ( "MBEDTLS_INCLUDE_DIR" ) )
299- {
300- println ! ( "Found environment varibales, using external MbedTLS" ) ;
301- lib = lib_dir;
302- include = include_dir;
303- statically = cfg ! ( feature = "static" ) || env:: var ( "MBEDCRYPTO_STATIC" ) . is_ok ( ) ;
304- external_mbedtls = true ;
305- } else {
306- println ! ( "Did not find environment variables, building MbedTLS!" ) ;
307- common:: configure_mbed_crypto ( ) ?;
308- let mut mbed_lib_dir = compile_mbed_crypto ( ) ?;
309- let mut mbed_include_dir = mbed_lib_dir. clone ( ) ;
310- mbed_lib_dir. push ( "lib" ) ;
311- if !mbed_lib_dir. as_path ( ) . exists ( ) {
312- _ = mbed_lib_dir. pop ( ) ;
313- mbed_lib_dir. push ( "lib64" ) ;
353+ match common:: get_external_mbedtls ( ) {
354+ Some ( result) => {
355+ let ( include_dir, lib_dir) = result. unwrap ( ) ;
356+ lib = lib_dir;
357+ include = include_dir;
358+ statically = cfg ! ( feature = "static" ) || env:: var ( "MBEDCRYPTO_STATIC" ) . is_ok ( ) ;
359+ external_mbedtls = true ;
314360 }
315- mbed_include_dir. push ( "include" ) ;
361+ None => {
362+ println ! ( "Did not find external MBEDTLS, building MbedTLS!" ) ;
363+ common:: configure_mbed_crypto ( ) ?;
364+ let mut mbed_lib_dir = compile_mbed_crypto ( ) ?;
365+ let mut mbed_include_dir = mbed_lib_dir. clone ( ) ;
366+ mbed_lib_dir. push ( "lib" ) ;
367+ if !mbed_lib_dir. as_path ( ) . exists ( ) {
368+ _ = mbed_lib_dir. pop ( ) ;
369+ mbed_lib_dir. push ( "lib64" ) ;
370+ }
371+ mbed_include_dir. push ( "include" ) ;
316372
317- lib = mbed_lib_dir. to_str ( ) . unwrap ( ) . to_owned ( ) ;
318- include = mbed_include_dir. to_str ( ) . unwrap ( ) . to_owned ( ) ;
319- statically = true ;
320- external_mbedtls = false ;
373+ lib = mbed_lib_dir. to_str ( ) . unwrap ( ) . to_owned ( ) ;
374+ include = mbed_include_dir. to_str ( ) . unwrap ( ) . to_owned ( ) ;
375+ statically = true ;
376+ external_mbedtls = false ;
377+ }
321378 }
322379
323380 // Linking to PSA Crypto library is only needed for the operations.
@@ -332,58 +389,52 @@ mod operations {
332389 #[ cfg( feature = "prefix" ) ]
333390 // Build script when the operations feature is on
334391 pub fn script_operations ( ) -> Result < ( ) > {
335- if env:: var ( "MBEDTLS_LIB_DIR" ) . is_err ( ) ^ env:: var ( "MBEDTLS_INCLUDE_DIR" ) . is_err ( ) {
336- return Err ( Error :: new (
337- ErrorKind :: Other ,
338- "both environment variables MBEDTLS_LIB_DIR and MBEDTLS_INCLUDE_DIR need to be set for operations feature" ,
339- ) ) ;
340- }
341-
342- if let ( Ok ( lib_dir) , Ok ( include_dir) ) =
343- ( env:: var ( "MBEDTLS_LIB_DIR" ) , env:: var ( "MBEDTLS_INCLUDE_DIR" ) )
344- {
345- println ! ( "Building with external MBEDTLS" ) ;
346-
347- // Request rustc to link the Mbed Crypto library
348- let link_type = if cfg ! ( feature = "static" ) || env:: var ( "MBEDCRYPTO_STATIC" ) . is_ok ( ) {
349- "static"
350- } else {
351- "dylib"
352- } ;
353- println ! ( "cargo:rustc-link-search=native={}" , lib_dir) ;
354- println ! ( "cargo:rustc-link-lib={}=mbedcrypto" , link_type) ;
355-
356- common:: generate_mbed_crypto_bindings ( include_dir. clone ( ) , true ) ?;
357- let _ = common:: compile_shim_library ( include_dir, true , true ) ?;
358- } else {
359- println ! ( "Did not find environment variables, building MbedTLS!" ) ;
360- common:: configure_mbed_crypto ( ) ?;
361- let mut mbed_lib_dir = compile_mbed_crypto ( ) ?;
362- let mut mbed_include_dir = mbed_lib_dir. clone ( ) ;
363- mbed_lib_dir. push ( "lib" ) ;
364- if !mbed_lib_dir. as_path ( ) . exists ( ) {
365- _ = mbed_lib_dir. pop ( ) ;
366- mbed_lib_dir. push ( "lib64" ) ;
392+ match common:: get_external_mbedtls ( ) {
393+ Some ( result) => {
394+ let ( include_dir, lib_dir) = result. unwrap ( ) ;
395+ // Request rustc to link the Mbed Crypto library
396+ let link_type = if cfg ! ( feature = "static" ) || env:: var ( "MBEDCRYPTO_STATIC" ) . is_ok ( )
397+ {
398+ "static"
399+ } else {
400+ "dylib"
401+ } ;
402+ println ! ( "cargo:rustc-link-search=native={}" , lib_dir) ;
403+ println ! ( "cargo:rustc-link-lib={}=mbedcrypto" , link_type) ;
404+
405+ common:: generate_mbed_crypto_bindings ( include_dir. clone ( ) , true ) ?;
406+ let _ = common:: compile_shim_library ( include_dir, true , true ) ?;
367407 }
408+ None => {
409+ println ! ( "Did not find environment variables, building MbedTLS!" ) ;
410+ common:: configure_mbed_crypto ( ) ?;
411+ let mut mbed_lib_dir = compile_mbed_crypto ( ) ?;
412+ let mut mbed_include_dir = mbed_lib_dir. clone ( ) ;
413+ mbed_lib_dir. push ( "lib" ) ;
414+ if !mbed_lib_dir. as_path ( ) . exists ( ) {
415+ _ = mbed_lib_dir. pop ( ) ;
416+ mbed_lib_dir. push ( "lib64" ) ;
417+ }
368418
369- mbed_include_dir. push ( "include" ) ;
370- let main_lib = mbed_lib_dir. join ( "libmbedcrypto.a" ) ;
371-
372- let include = mbed_include_dir. to_str ( ) . unwrap ( ) . to_owned ( ) ;
373- common:: generate_mbed_crypto_bindings ( include. clone ( ) , false ) ?;
374- let shim_lib = common:: compile_shim_library ( include, false , false ) ?;
375-
376- // Modify and copy the libraries into a new directory.
377- let llib_path = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) . join ( "llib" ) ;
378- let main_lib_name = prefix ( ) + "mbedcrypto" ;
379- let shim_lib_name = prefix ( ) + "shim" ;
380- objcopy ( vec ! [
381- ( main_lib, llib_path. join( format!( "lib{}.a" , main_lib_name) ) ) ,
382- ( shim_lib, llib_path. join( format!( "lib{}.a" , shim_lib_name) ) ) ,
383- ] ) ?;
384- println ! ( "cargo:rustc-link-search=native={}" , llib_path. display( ) ) ;
385- println ! ( "cargo:rustc-link-lib=static={}" , main_lib_name) ;
386- println ! ( "cargo:rustc-link-lib=static={}" , shim_lib_name) ;
419+ mbed_include_dir. push ( "include" ) ;
420+ let main_lib = mbed_lib_dir. join ( "libmbedcrypto.a" ) ;
421+
422+ let include = mbed_include_dir. to_str ( ) . unwrap ( ) . to_owned ( ) ;
423+ common:: generate_mbed_crypto_bindings ( include. clone ( ) , false ) ?;
424+ let shim_lib = common:: compile_shim_library ( include, false , false ) ?;
425+
426+ // Modify and copy the libraries into a new directory.
427+ let llib_path = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) . join ( "llib" ) ;
428+ let main_lib_name = prefix ( ) + "mbedcrypto" ;
429+ let shim_lib_name = prefix ( ) + "shim" ;
430+ objcopy ( vec ! [
431+ ( main_lib, llib_path. join( format!( "lib{}.a" , main_lib_name) ) ) ,
432+ ( shim_lib, llib_path. join( format!( "lib{}.a" , shim_lib_name) ) ) ,
433+ ] ) ?;
434+ println ! ( "cargo:rustc-link-search=native={}" , llib_path. display( ) ) ;
435+ println ! ( "cargo:rustc-link-lib=static={}" , main_lib_name) ;
436+ println ! ( "cargo:rustc-link-lib=static={}" , shim_lib_name) ;
437+ }
387438 }
388439
389440 Ok ( ( ) )
0 commit comments