@@ -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