@@ -332,6 +332,7 @@ pub struct Build {
332
332
shell_escaped_flags : Option < bool > ,
333
333
build_cache : Arc < BuildCache > ,
334
334
inherit_rustflags : bool ,
335
+ link_shared_flag : bool ,
335
336
}
336
337
337
338
/// Represents the types of errors that may occur while using cc-rs.
@@ -459,6 +460,7 @@ impl Build {
459
460
shell_escaped_flags : None ,
460
461
build_cache : Arc :: default ( ) ,
461
462
inherit_rustflags : true ,
463
+ link_shared_flag : false ,
462
464
}
463
465
}
464
466
@@ -1227,6 +1229,14 @@ impl Build {
1227
1229
self
1228
1230
}
1229
1231
1232
+ /// Configure whether cc should build dynamic library and link with `rustc-link-lib=dylib`
1233
+ ///
1234
+ /// This option defaults to `false`.
1235
+ pub fn link_shared_flag ( & mut self , link_shared_flag : bool ) -> & mut Build {
1236
+ self . link_shared_flag = link_shared_flag;
1237
+ self
1238
+ }
1239
+
1230
1240
#[ doc( hidden) ]
1231
1241
pub fn __set_env < A , B > ( & mut self , a : A , b : B ) -> & mut Build
1232
1242
where
@@ -1380,6 +1390,22 @@ impl Build {
1380
1390
Ok ( is_supported)
1381
1391
}
1382
1392
1393
+ fn get_canonical_library_names ( name : & str ) -> ( & str , String , String ) {
1394
+ let lib_striped = name. strip_prefix ( "lib" ) . unwrap_or ( name) ;
1395
+ let lib_name = if lib_striped. ends_with ( ".a" ) {
1396
+ & lib_striped[ ..lib_striped. len ( ) - 2 ]
1397
+ } else if lib_striped. ends_with ( ".so" ) {
1398
+ & lib_striped[ ..lib_striped. len ( ) - 3 ]
1399
+ } else {
1400
+ lib_striped
1401
+ } ;
1402
+ (
1403
+ lib_name,
1404
+ format ! ( "lib{lib_name}.a" ) ,
1405
+ format ! ( "lib{lib_name}.so" ) ,
1406
+ )
1407
+ }
1408
+
1383
1409
/// Run the compiler, generating the file `output`
1384
1410
///
1385
1411
/// This will return a result instead of panicking; see [`Self::compile()`] for
@@ -1396,21 +1422,25 @@ impl Build {
1396
1422
}
1397
1423
}
1398
1424
1399
- let ( lib_name, gnu_lib_name) = if output. starts_with ( "lib" ) && output. ends_with ( ".a" ) {
1400
- ( & output[ 3 ..output. len ( ) - 2 ] , output. to_owned ( ) )
1401
- } else {
1402
- let mut gnu = String :: with_capacity ( 5 + output. len ( ) ) ;
1403
- gnu. push_str ( "lib" ) ;
1404
- gnu. push_str ( output) ;
1405
- gnu. push_str ( ".a" ) ;
1406
- ( output, gnu)
1407
- } ;
1425
+ let ( lib_name, static_name, dynlib_name) = Self :: get_canonical_library_names ( output) ;
1408
1426
let dst = self . get_out_dir ( ) ?;
1409
1427
1410
1428
let objects = objects_from_files ( & self . files , & dst) ?;
1411
1429
1412
1430
self . compile_objects ( & objects) ?;
1413
- self . assemble ( lib_name, & dst. join ( gnu_lib_name) , & objects) ?;
1431
+
1432
+ if self . link_shared_flag {
1433
+ let objects = objects. iter ( ) . map ( |o| o. dst . clone ( ) ) . collect :: < Vec < _ > > ( ) ;
1434
+
1435
+ let mut command = self . try_get_compiler ( ) ?. to_command ( ) ;
1436
+ let cmd = command
1437
+ . args ( [ "-shared" , "-o" ] )
1438
+ . arg ( dst. join ( dynlib_name) )
1439
+ . args ( & objects) ;
1440
+ run ( cmd, & self . cargo_output ) ?;
1441
+ }
1442
+
1443
+ self . assemble ( lib_name, & dst. join ( static_name) , & objects) ?;
1414
1444
1415
1445
let target = self . get_target ( ) ?;
1416
1446
if target. env == "msvc" {
@@ -1435,8 +1465,13 @@ impl Build {
1435
1465
}
1436
1466
1437
1467
if self . link_lib_modifiers . is_empty ( ) {
1438
- self . cargo_output
1439
- . print_metadata ( & format_args ! ( "cargo:rustc-link-lib=static={}" , lib_name) ) ;
1468
+ if self . link_shared_flag {
1469
+ self . cargo_output
1470
+ . print_metadata ( & format_args ! ( "cargo:rustc-link-lib=dylib={}" , lib_name) ) ;
1471
+ } else {
1472
+ self . cargo_output
1473
+ . print_metadata ( & format_args ! ( "cargo:rustc-link-lib=static={}" , lib_name) ) ;
1474
+ }
1440
1475
} else {
1441
1476
self . cargo_output . print_metadata ( & format_args ! (
1442
1477
"cargo:rustc-link-lib=static:{}={}" ,
0 commit comments