35
35
#![ allow( clippy:: multiple_crate_versions) ]
36
36
37
37
fn main ( ) -> std:: io:: Result < ( ) > {
38
+ // If the prefix feature is not enabled then set the "CARGO_PKG_LINKS"
39
+ // parameter to mbedcrypto to avoid any duplicate symbols from any other
40
+ // crate. "CARGO_PKG_LINKS" overrides the "links" field in the manifest.
41
+ #[ cfg( not( feature = "prefix" ) ) ]
42
+ {
43
+ use std:: env;
44
+ let cargo_pkg_links = "CARGO_PKG_LINKS" ;
45
+ env:: set_var ( cargo_pkg_links, "mbedcrypto" ) ;
46
+ }
47
+
38
48
#[ cfg( feature = "operations" ) ]
39
49
return operations:: script_operations ( ) ;
40
50
@@ -47,7 +57,9 @@ fn main() -> std::io::Result<()> {
47
57
48
58
#[ cfg( any( feature = "interface" , feature = "operations" ) ) ]
49
59
mod common {
60
+ #[ cfg( feature = "prefix" ) ]
50
61
use bindgen:: callbacks:: { ItemInfo , ParseCallbacks } ;
62
+
51
63
use std:: env;
52
64
use std:: io:: { Error , ErrorKind , Result } ;
53
65
use std:: path:: { Path , PathBuf } ;
@@ -87,17 +99,21 @@ mod common {
87
99
Ok ( ( ) )
88
100
}
89
101
102
+ #[ cfg( feature = "prefix" ) ]
90
103
// Cargo provides the crate version from Cargo.toml in the environment.
91
104
const VERSION : & str = env ! ( "CARGO_PKG_VERSION" ) ;
92
105
106
+ #[ cfg( feature = "prefix" ) ]
93
107
// Return a prefix that we hope is globally unique.
94
108
pub fn prefix ( ) -> String {
95
109
format ! ( "psa_crypto_{}_" , VERSION . replace( '.' , "_" ) )
96
110
}
97
111
112
+ #[ cfg( feature = "prefix" ) ]
98
113
#[ derive( Debug ) ]
99
114
struct RenameCallbacks { }
100
115
116
+ #[ cfg( feature = "prefix" ) ]
101
117
impl ParseCallbacks for RenameCallbacks {
102
118
fn generated_link_name_override ( & self , info : ItemInfo < ' _ > ) -> Option < String > {
103
119
Some ( prefix ( ) + info. name )
@@ -111,6 +127,24 @@ mod common {
111
127
112
128
let out_dir = env:: var ( "OUT_DIR" ) . unwrap ( ) ;
113
129
130
+ #[ cfg( not( feature = "prefix" ) ) ]
131
+ let shim_bindings = bindgen:: Builder :: default ( )
132
+ . clang_arg ( format ! ( "-I{}" , out_dir) )
133
+ . clang_arg ( "-DMBEDTLS_CONFIG_FILE=<config.h>" )
134
+ . clang_arg ( format ! ( "-I{}" , mbed_include_dir) )
135
+ . header ( "src/c/shim.h" )
136
+ . blocklist_type ( "max_align_t" )
137
+ . generate_comments ( false )
138
+ . size_t_is_usize ( true )
139
+ . generate ( )
140
+ . map_err ( |_| {
141
+ Error :: new (
142
+ ErrorKind :: Other ,
143
+ "Unable to generate bindings to mbed crypto" ,
144
+ )
145
+ } ) ?;
146
+
147
+ #[ cfg( feature = "prefix" ) ]
114
148
let shim_bindings = bindgen:: Builder :: default ( )
115
149
. clang_arg ( format ! ( "-I{}" , out_dir) )
116
150
. clang_arg ( "-DMBEDTLS_CONFIG_FILE=<config.h>" )
@@ -127,6 +161,7 @@ mod common {
127
161
"Unable to generate bindings to mbed crypto" ,
128
162
)
129
163
} ) ?;
164
+
130
165
let out_path = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ;
131
166
shim_bindings. write_to_file ( out_path. join ( "shim_bindings.rs" ) ) ?;
132
167
@@ -136,6 +171,8 @@ mod common {
136
171
pub fn compile_shim_library ( include_dir : String , metadata : bool ) -> Result < PathBuf > {
137
172
let out_dir = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ;
138
173
174
+ let shimlib_name = "libmbedcryptoshim.a" ;
175
+
139
176
// Compile and package the shim library
140
177
cc:: Build :: new ( )
141
178
. include ( & out_dir)
@@ -146,10 +183,19 @@ mod common {
146
183
. flag ( "-Werror" )
147
184
. opt_level ( 2 )
148
185
. cargo_metadata ( metadata)
149
- . try_compile ( "libmbedcryptoshim.a" )
186
+ . try_compile ( shimlib_name )
150
187
. map_err ( |_| Error :: new ( ErrorKind :: Other , "compiling shim.c failed" ) ) ?;
151
188
152
- Ok ( out_dir. join ( "libmbedcryptoshim.a" ) )
189
+ // Also link shim library
190
+ #[ cfg( not( feature = "prefix" ) ) ]
191
+ {
192
+ println ! (
193
+ "cargo:rustc-link-search=native={}" ,
194
+ env:: var( "OUT_DIR" ) . unwrap( )
195
+ ) ;
196
+ println ! ( "cargo:rustc-link-lib=static=mbedcryptoshim" ) ;
197
+ }
198
+ Ok ( out_dir. join ( shimlib_name) )
153
199
}
154
200
}
155
201
@@ -178,10 +224,13 @@ mod interface {
178
224
#[ cfg( feature = "operations" ) ]
179
225
mod operations {
180
226
use super :: common;
227
+ #[ cfg( feature = "prefix" ) ]
181
228
use super :: common:: prefix;
182
229
use cmake:: Config ;
183
230
use std:: env;
184
- use std:: io:: { Error , ErrorKind , Result , Write } ;
231
+ #[ cfg( feature = "prefix" ) ]
232
+ use std:: io:: Write ;
233
+ use std:: io:: { Error , ErrorKind , Result } ;
185
234
use std:: path:: PathBuf ;
186
235
use walkdir:: WalkDir ;
187
236
@@ -212,17 +261,66 @@ mod operations {
212
261
Ok ( mbed_build_path)
213
262
}
214
263
264
+ #[ cfg( not( feature = "prefix" ) ) ]
265
+ fn link_to_lib ( lib_path : String , link_statically : bool ) {
266
+ let link_type = if link_statically { "static" } else { "dylib" } ;
267
+
268
+ // Request rustc to link the Mbed Crypto library
269
+ println ! ( "cargo:rustc-link-search=native={}" , lib_path, ) ;
270
+ println ! ( "cargo:rustc-link-lib={}=mbedcrypto" , link_type) ;
271
+ }
272
+
273
+ #[ cfg( not( feature = "prefix" ) ) ]
215
274
// Build script when the operations feature is on
216
275
pub fn script_operations ( ) -> Result < ( ) > {
276
+ let lib;
277
+ let statically;
278
+ let include;
279
+
217
280
if env:: var ( "MBEDTLS_LIB_DIR" ) . is_err ( ) ^ env:: var ( "MBEDTLS_INCLUDE_DIR" ) . is_err ( ) {
218
281
return Err ( Error :: new (
219
282
ErrorKind :: Other ,
220
283
"both environment variables MBEDTLS_LIB_DIR and MBEDTLS_INCLUDE_DIR need to be set for operations feature" ,
221
284
) ) ;
222
285
}
223
-
224
286
common:: configure_mbed_crypto ( ) ?;
287
+ if let ( Ok ( lib_dir) , Ok ( include_dir) ) =
288
+ ( env:: var ( "MBEDTLS_LIB_DIR" ) , env:: var ( "MBEDTLS_INCLUDE_DIR" ) )
289
+ {
290
+ lib = lib_dir;
291
+ include = include_dir;
292
+ statically = cfg ! ( feature = "static" ) || env:: var ( "MBEDCRYPTO_STATIC" ) . is_ok ( ) ;
293
+ } else {
294
+ println ! ( "Did not find environment variables, building MbedTLS!" ) ;
295
+ let mut mbed_lib_dir = compile_mbed_crypto ( ) ?;
296
+ let mut mbed_include_dir = mbed_lib_dir. clone ( ) ;
297
+ mbed_lib_dir. push ( "lib" ) ;
298
+ mbed_include_dir. push ( "include" ) ;
299
+
300
+ lib = mbed_lib_dir. to_str ( ) . unwrap ( ) . to_owned ( ) ;
301
+ include = mbed_include_dir. to_str ( ) . unwrap ( ) . to_owned ( ) ;
302
+ statically = true ;
303
+ }
304
+
305
+ // Linking to PSA Crypto library is only needed for the operations.
306
+ link_to_lib ( lib, statically) ;
307
+ common:: generate_mbed_crypto_bindings ( include. clone ( ) ) ?;
308
+ match common:: compile_shim_library ( include, false ) {
309
+ Ok ( _) => Ok ( ( ) ) ,
310
+ Err ( e) => Err ( e) ,
311
+ }
312
+ }
225
313
314
+ #[ cfg( feature = "prefix" ) ]
315
+ // Build script when the operations feature is on
316
+ pub fn script_operations ( ) -> Result < ( ) > {
317
+ if env:: var ( "MBEDTLS_LIB_DIR" ) . is_err ( ) ^ env:: var ( "MBEDTLS_INCLUDE_DIR" ) . is_err ( ) {
318
+ return Err ( Error :: new (
319
+ ErrorKind :: Other ,
320
+ "both environment variables MBEDTLS_LIB_DIR and MBEDTLS_INCLUDE_DIR need to be set for operations feature" ,
321
+ ) ) ;
322
+ }
323
+ common:: configure_mbed_crypto ( ) ?;
226
324
if let ( Ok ( lib_dir) , Ok ( include_dir) ) =
227
325
( env:: var ( "MBEDTLS_LIB_DIR" ) , env:: var ( "MBEDTLS_INCLUDE_DIR" ) )
228
326
{
@@ -265,6 +363,7 @@ mod operations {
265
363
Ok ( ( ) )
266
364
}
267
365
366
+ #[ cfg( feature = "prefix" ) ]
268
367
pub fn objcopy ( liblist : Vec < ( PathBuf , PathBuf ) > ) -> Result < ( ) > {
269
368
// Run nm on the source libraries.
270
369
let mut args = vec ! [ ] ;
0 commit comments