@@ -333,6 +333,7 @@ pub struct Build {
333333 build_cache : Arc < BuildCache > ,
334334 inherit_rustflags : bool ,
335335 link_shared_flag : bool ,
336+ shared_lib_out_dir : Option < Arc < Path > > ,
336337}
337338
338339/// Represents the types of errors that may occur while using cc-rs.
@@ -461,6 +462,7 @@ impl Build {
461462 build_cache : Arc :: default ( ) ,
462463 inherit_rustflags : true ,
463464 link_shared_flag : false ,
465+ shared_lib_out_dir : None ,
464466 }
465467 }
466468
@@ -1237,6 +1239,14 @@ impl Build {
12371239 self
12381240 }
12391241
1242+ /// Configures the output directory where shared library will be located.
1243+ ///
1244+ /// This option is automatically scraped from the `OUT_DIR` environment variable by build scripts
1245+ pub fn shared_lib_out_dir < P : AsRef < Path > > ( & mut self , out_dir : P ) -> & mut Build {
1246+ self . shared_lib_out_dir = Some ( out_dir. as_ref ( ) . into ( ) ) ;
1247+ self
1248+ }
1249+
12401250 #[ doc( hidden) ]
12411251 pub fn __set_env < A , B > ( & mut self , a : A , b : B ) -> & mut Build
12421252 where
@@ -1390,16 +1400,26 @@ impl Build {
13901400 Ok ( is_supported)
13911401 }
13921402
1393- fn get_canonical_library_names ( name : & str ) -> ( & str , String , String ) {
1394- let lib_striped = name. strip_prefix ( "lib" ) . unwrap_or ( name) ;
1403+ /// Get canonical library names for `output`
1404+ fn get_canonical_library_names < ' a > (
1405+ & self ,
1406+ output : & ' a str ,
1407+ ) -> Result < ( & ' a str , String , String ) , Error > {
1408+ let lib_striped = output. strip_prefix ( "lib" ) . unwrap_or ( output) ;
13951409 let static_striped = lib_striped. strip_suffix ( ".a" ) . unwrap_or ( lib_striped) ;
1396- let lib_name = lib_striped. strip_suffix ( ".so" ) . unwrap_or ( static_striped) ;
13971410
1398- (
1411+ let dyn_ext = if self . get_target ( ) ?. env == "msvc" {
1412+ ".dll"
1413+ } else {
1414+ ".so"
1415+ } ;
1416+ let lib_name = lib_striped. strip_suffix ( dyn_ext) . unwrap_or ( static_striped) ;
1417+
1418+ Ok ( (
13991419 lib_name,
14001420 format ! ( "lib{lib_name}.a" ) ,
1401- format ! ( "lib{lib_name}.so " ) ,
1402- )
1421+ format ! ( "lib{lib_name}{dyn_ext} " ) ,
1422+ ) )
14031423 }
14041424
14051425 /// Run the compiler, generating the file `output`
@@ -1418,7 +1438,7 @@ impl Build {
14181438 }
14191439 }
14201440
1421- let ( lib_name, static_name, dynlib_name) = Self :: get_canonical_library_names ( output) ;
1441+ let ( lib_name, static_name, dynlib_name) = self . get_canonical_library_names ( output) ? ;
14221442 let dst = self . get_out_dir ( ) ?;
14231443
14241444 let objects = objects_from_files ( & self . files , & dst) ?;
@@ -1428,12 +1448,13 @@ impl Build {
14281448 if self . link_shared_flag {
14291449 let objects = objects. iter ( ) . map ( |o| o. dst . clone ( ) ) . collect :: < Vec < _ > > ( ) ;
14301450
1431- let mut command = self . try_get_compiler ( ) ?. to_command ( ) ;
1432- let cmd = command
1433- . args ( [ "-shared" , "-o" ] )
1434- . arg ( dst. join ( dynlib_name) )
1435- . args ( & objects) ;
1436- run ( cmd, & self . cargo_output ) ?;
1451+ let mut cmd = self . try_get_compiler ( ) ?. to_command ( ) ;
1452+ let dynlib_path = dst. join ( & dynlib_name) ;
1453+ cmd. args ( [ "-shared" , "-o" ] ) . arg ( & dynlib_path) . args ( & objects) ;
1454+ run ( & mut cmd, & self . cargo_output ) ?;
1455+ if let Some ( out_dir) = & self . shared_lib_out_dir {
1456+ fs:: copy ( dynlib_path, out_dir. join ( & dynlib_name) ) ?;
1457+ }
14371458 } else {
14381459 self . assemble ( lib_name, & dst. join ( static_name) , & objects) ?;
14391460 }
0 commit comments