@@ -39,7 +39,7 @@ clippy::all
3939#![ forbid(
4040 unsafe_code,
4141 // intra_doc_link_resolution_failure, broken_intra_doc_links
42- safe_packed_borrows ,
42+ unaligned_references ,
4343 while_true,
4444 bare_trait_objects
4545) ]
@@ -159,51 +159,49 @@ impl CFormatting for ReturnType {
159159
160160pub struct CBindgenConfig {
161161 pub output_dir : PathBuf ,
162+ pub ffi_target_name : String ,
162163 pub ffi_name : String ,
164+ pub is_release : bool ,
163165 pub extra_files : Vec < PathBuf > ,
164- pub platforms : PlatformLocations ,
166+ pub platform_location : PlatformLocation ,
165167}
166168
167169pub fn generate_c_package ( lib : & Library , config : & CBindgenConfig ) -> FormattingResult < ( ) > {
168- for platform in config. platforms . iter ( ) {
169- generate_single_package ( lib, config, & platform) ?;
170- }
171-
172- Ok ( ( ) )
173- }
174-
175- fn generate_single_package (
176- lib : & Library ,
177- config : & CBindgenConfig ,
178- platform_location : & PlatformLocation ,
179- ) -> FormattingResult < ( ) > {
180170 let output_dir = config
181171 . output_dir
182- . join ( platform_location. platform . to_string ( ) ) ;
172+ . join ( config . platform_location . platform . as_string ( ) ) ;
183173
184174 // Create header file
185175 let include_path = output_dir. join ( "include" ) ;
186176 generate_c_header ( lib, include_path) ?;
187177
188178 // Generate CMake config file
189- generate_cmake_config ( lib, config, & platform_location) ?;
179+ generate_cmake_config ( lib, config, & config . platform_location ) ?;
190180
191181 // Copy lib files (lib and DLL on Windows, .so on Linux)
192182 let lib_path = output_dir
193183 . join ( "lib" )
194- . join ( platform_location. platform . to_string ( ) ) ;
184+ . join ( config . platform_location . platform . as_string ( ) ) ;
195185 fs:: create_dir_all ( & lib_path) ?;
196186
197- let lib_filename = platform_location. lib_filename ( & config. ffi_name ) ;
187+ let lib_filename = config
188+ . platform_location
189+ . static_lib_filename ( & config. ffi_name ) ;
198190 fs:: copy (
199- platform_location. location . join ( & lib_filename) ,
191+ config. platform_location . location . join ( & lib_filename) ,
192+ lib_path. join ( & lib_filename) ,
193+ ) ?;
194+
195+ let lib_filename = config. platform_location . dyn_lib_filename ( & config. ffi_name ) ;
196+ fs:: copy (
197+ config. platform_location . location . join ( & lib_filename) ,
200198 lib_path. join ( & lib_filename) ,
201199 ) ?;
202200
203201 // Copy DLL on Windows
204- let bin_filename = platform_location. bin_filename ( & config. ffi_name ) ;
202+ let bin_filename = config . platform_location . bin_filename ( & config. ffi_name ) ;
205203 fs:: copy (
206- platform_location. location . join ( & bin_filename) ,
204+ config . platform_location . location . join ( & bin_filename) ,
207205 lib_path. join ( & bin_filename) ,
208206 ) ?;
209207
@@ -243,7 +241,7 @@ pub fn generate_doxygen(lib: &Library, config: &CBindgenConfig) -> FormattingRes
243241 . write_all (
244242 & format ! (
245243 "INPUT = {}/include\n " ,
246- config. platforms . iter ( ) . next ( ) . unwrap ( ) . platform. to_string ( )
244+ config. platform_location . platform. as_string ( )
247245 )
248246 . into_bytes ( ) ,
249247 )
@@ -1002,30 +1000,100 @@ fn generate_cmake_config(
10021000 // Create file
10031001 let cmake_path = config
10041002 . output_dir
1005- . join ( platform_location. platform . to_string ( ) )
1003+ . join ( platform_location. platform . as_string ( ) )
10061004 . join ( "cmake" ) ;
10071005 fs:: create_dir_all ( & cmake_path) ?;
10081006 let filename = cmake_path. join ( format ! ( "{}-config.cmake" , lib. name) ) ;
10091007 let mut f = FilePrinter :: new ( filename) ?;
10101008
1009+ let link_deps = get_link_dependencies ( config) ;
1010+
10111011 // Prefix used everywhere else
10121012 f. writeln ( "set(prefix \" ${CMAKE_CURRENT_LIST_DIR}/../\" )" ) ?;
10131013 f. newline ( ) ?;
10141014
1015+ // Write dynamic library version
10151016 f. writeln ( & format ! ( "add_library({} SHARED IMPORTED GLOBAL)" , lib. name) ) ?;
10161017 f. writeln ( & format ! ( "set_target_properties({} PROPERTIES" , lib. name) ) ?;
10171018 indented ( & mut f, |f| {
10181019 f. writeln ( & format ! (
10191020 "IMPORTED_LOCATION \" ${{prefix}}/lib/{}/{}\" " ,
1020- platform_location. platform. to_string ( ) ,
1021+ platform_location. platform. as_string ( ) ,
10211022 platform_location. bin_filename( & config. ffi_name)
10221023 ) ) ?;
10231024 f. writeln ( & format ! (
10241025 "IMPORTED_IMPLIB \" ${{prefix}}/lib/{}/{}\" " ,
1025- platform_location. platform. to_string ( ) ,
1026- platform_location. lib_filename ( & config. ffi_name)
1026+ platform_location. platform. as_string ( ) ,
1027+ platform_location. dyn_lib_filename ( & config. ffi_name)
10271028 ) ) ?;
10281029 f. writeln ( "INTERFACE_INCLUDE_DIRECTORIES \" ${prefix}/include\" " )
10291030 } ) ?;
1031+ f. writeln ( ")" ) ?;
1032+
1033+ f. newline ( ) ?;
1034+
1035+ // Write static library
1036+ f. writeln ( & format ! (
1037+ "add_library({}_static STATIC IMPORTED GLOBAL)" ,
1038+ lib. name
1039+ ) ) ?;
1040+ f. writeln ( & format ! (
1041+ "set_target_properties({}_static PROPERTIES" ,
1042+ lib. name
1043+ ) ) ?;
1044+ indented ( & mut f, |f| {
1045+ f. writeln ( & format ! (
1046+ "IMPORTED_LOCATION \" ${{prefix}}/lib/{}/{}\" " ,
1047+ platform_location. platform. as_string( ) ,
1048+ platform_location. static_lib_filename( & config. ffi_name)
1049+ ) ) ?;
1050+ f. writeln ( "INTERFACE_INCLUDE_DIRECTORIES \" ${prefix}/include\" " ) ?;
1051+ f. writeln ( & format ! (
1052+ "INTERFACE_LINK_LIBRARIES \" {}\" " ,
1053+ link_deps. join( ";" )
1054+ ) )
1055+ } ) ?;
10301056 f. writeln ( ")" )
10311057}
1058+
1059+ fn get_link_dependencies ( config : & CBindgenConfig ) -> Vec < String > {
1060+ let mut args = Vec :: from ( [ "rustc" , "-p" , & config. ffi_target_name ] ) ;
1061+
1062+ if config. is_release {
1063+ args. push ( "--release" ) ;
1064+ }
1065+
1066+ args. extend ( & [ "--" , "--print" , "native-static-libs" ] ) ;
1067+
1068+ let output = Command :: new ( "cargo" )
1069+ . args ( & args)
1070+ . output ( )
1071+ . expect ( "failed to run cargo" ) ;
1072+
1073+ if !output. status . success ( ) {
1074+ panic ! ( "failed to get the link dependencies" ) ;
1075+ }
1076+
1077+ // It prints to stderr for some reason
1078+ let result = String :: from_utf8_lossy ( & output. stderr ) ;
1079+
1080+ // Find where the libs are written
1081+ const PATTERN : & str = "native-static-libs: " ;
1082+ let pattern_idx = result
1083+ . find ( PATTERN )
1084+ . expect ( "failed to parse link dependencies" ) ;
1085+ let deps = & result[ pattern_idx + PATTERN . len ( ) ..result. len ( ) ] ;
1086+ let endline = deps. find ( '\n' ) . expect ( "failed to parse link dependencies" ) ;
1087+ let deps = & deps[ 0 ..endline] ;
1088+
1089+ // Extract the libs
1090+ let mut result = deps
1091+ . split_whitespace ( )
1092+ . map ( |x| x. to_owned ( ) )
1093+ . collect :: < Vec < _ > > ( ) ;
1094+
1095+ // Remove duplicates
1096+ result. dedup ( ) ;
1097+
1098+ result
1099+ }
0 commit comments