@@ -7,7 +7,7 @@ use std::{env, fmt, iter};
7
7
use dunce:: canonicalize;
8
8
use semver:: Version ;
9
9
10
- use super :: cmake_probe:: CmakeProbe ;
10
+ use super :: cmake_probe:: { CmakeProbe , LinkLib , LinkSearch } ;
11
11
use super :: { cleanup_lib_filename, get_version_from_headers, Result , MANIFEST_DIR , OUT_DIR , TARGET_VENDOR_APPLE } ;
12
12
13
13
struct PackageName ;
@@ -86,6 +86,25 @@ impl fmt::Display for EnvList<'_> {
86
86
}
87
87
}
88
88
89
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
90
+ pub enum Linkage {
91
+ Default ,
92
+ Dynamic ,
93
+ Static ,
94
+ Framework ,
95
+ }
96
+
97
+ impl Linkage {
98
+ pub fn as_cargo_rustc_link_spec ( self ) -> & ' static str {
99
+ match self {
100
+ Self :: Default => "" ,
101
+ Self :: Dynamic => "dylib=" ,
102
+ Self :: Static => "static=" ,
103
+ Self :: Framework => "framework=" ,
104
+ }
105
+ }
106
+ }
107
+
89
108
#[ derive( Debug ) ]
90
109
pub struct Library {
91
110
pub include_paths : Vec < PathBuf > ,
@@ -94,22 +113,12 @@ pub struct Library {
94
113
}
95
114
96
115
impl Library {
97
- fn process_library_list ( libs : impl IntoIterator < Item = impl AsRef < Path > > ) -> impl Iterator < Item = String > {
98
- libs. into_iter ( ) . filter_map ( |x| {
99
- let path = x. as_ref ( ) ;
100
- let is_framework = path
101
- . extension ( )
102
- . and_then ( OsStr :: to_str)
103
- . map_or ( false , |e| e. eq_ignore_ascii_case ( "framework" ) ) ;
116
+ fn process_library_list ( libs : impl IntoIterator < Item = LinkLib > ) -> impl Iterator < Item = LinkLib > {
117
+ libs. into_iter ( ) . filter_map ( |LinkLib ( linkage, path) | {
118
+ let path = Path :: new ( & path) ;
104
119
if let Some ( filename) = path. file_name ( ) {
105
120
let filename = cleanup_lib_filename ( filename) . unwrap_or ( filename) ;
106
- filename. to_str ( ) . map ( |f| {
107
- if is_framework {
108
- format ! ( "framework={f}" )
109
- } else {
110
- f. to_owned ( )
111
- }
112
- } )
121
+ filename. to_str ( ) . map ( |f| LinkLib ( linkage, f. to_owned ( ) ) )
113
122
} else {
114
123
None
115
124
}
@@ -120,34 +129,6 @@ impl Library {
120
129
include_paths. into_iter ( ) . find_map ( |x| get_version_from_headers ( x. as_ref ( ) ) )
121
130
}
122
131
123
- #[ inline]
124
- fn emit_link_search ( path : & Path , typ : Option < & str > ) -> String {
125
- format ! (
126
- "cargo:rustc-link-search={}{}" ,
127
- typ. map_or_else( || "" . to_string( ) , |t| format!( "{t}=" ) ) ,
128
- path. to_str( ) . expect( "Can't convert link search path to UTF-8 string" )
129
- )
130
- }
131
-
132
- #[ inline]
133
- fn emit_link_lib ( lib : & str , typ : Option < & str > ) -> String {
134
- format ! (
135
- "cargo:rustc-link-lib={}{}" ,
136
- typ. map_or_else(
137
- || "" . to_string( ) ,
138
- |t| {
139
- let prefix = format!( "{t}=" ) ;
140
- if lib. starts_with( & prefix) {
141
- "" . to_string( )
142
- } else {
143
- prefix
144
- }
145
- }
146
- ) ,
147
- lib
148
- )
149
- }
150
-
151
132
fn process_env_var_list < ' a , T : From < & ' a str > > ( env_list : Option < EnvList < ' a > > , sys_list : Vec < T > ) -> Vec < T > {
152
133
if let Some ( env_list) = env_list {
153
134
let mut paths = if env_list. is_extend ( ) {
@@ -162,25 +143,19 @@ impl Library {
162
143
}
163
144
}
164
145
165
- fn process_link_paths < ' a > (
166
- link_paths : Option < EnvList > ,
167
- sys_link_paths : Vec < PathBuf > ,
168
- typ : Option < & ' a str > ,
169
- ) -> impl Iterator < Item = String > + ' a {
146
+ fn process_link_paths < ' a > ( link_paths : Option < EnvList > , sys_link_paths : Vec < LinkSearch > ) -> impl Iterator < Item = String > + ' a {
170
147
Self :: process_env_var_list ( link_paths, sys_link_paths)
171
148
. into_iter ( )
172
149
. flat_map ( move |path| {
173
- iter:: once ( Self :: emit_link_search ( & path, typ) )
174
- . chain ( TARGET_VENDOR_APPLE . then ( || Self :: emit_link_search ( & path, Some ( "framework" ) ) ) )
150
+ iter:: once ( path. emit_cargo_rustc_link_search ( ) ) . chain (
151
+ ( * TARGET_VENDOR_APPLE && path. 0 != Linkage :: Framework )
152
+ . then ( || LinkSearch ( Linkage :: Framework , path. 1 ) . emit_cargo_rustc_link_search ( ) ) ,
153
+ )
175
154
} )
176
155
}
177
156
178
- fn process_link_libs < ' a > (
179
- link_libs : Option < EnvList > ,
180
- sys_link_libs : Vec < String > ,
181
- typ : Option < & ' a str > ,
182
- ) -> impl Iterator < Item = String > + ' a {
183
- Self :: process_library_list ( Self :: process_env_var_list ( link_libs, sys_link_libs) ) . map ( move |l| Self :: emit_link_lib ( & l, typ) )
157
+ fn process_link_libs < ' a > ( link_libs : Option < EnvList > , sys_link_libs : Vec < LinkLib > ) -> impl Iterator < Item = String > + ' a {
158
+ Self :: process_library_list ( Self :: process_env_var_list ( link_libs, sys_link_libs) ) . map ( |l| l. emit_cargo_rustc_link ( ) )
184
159
}
185
160
186
161
fn find_vcpkg_tool ( vcpkg_root : & Path , tool_name : & str ) -> Option < PathBuf > {
@@ -228,8 +203,8 @@ impl Library {
228
203
229
204
let version = Self :: version_from_include_paths ( & include_paths) . ok_or ( "could not get versions from header files" ) ?;
230
205
231
- cargo_metadata. extend ( Self :: process_link_paths ( Some ( link_paths) , vec ! [ ] , None ) ) ;
232
- cargo_metadata. extend ( Self :: process_link_libs ( Some ( link_libs) , vec ! [ ] , None ) ) ;
206
+ cargo_metadata. extend ( Self :: process_link_paths ( Some ( link_paths) , vec ! [ ] ) ) ;
207
+ cargo_metadata. extend ( Self :: process_link_libs ( Some ( link_libs) , vec ! [ ] ) ) ;
233
208
234
209
Ok ( Self {
235
210
include_paths,
@@ -266,14 +241,38 @@ impl Library {
266
241
let opencv = opencv. ok_or_else ( || errors. join ( ", " ) ) ?;
267
242
let mut cargo_metadata = Vec :: with_capacity ( 64 ) ;
268
243
269
- cargo_metadata. extend ( Self :: process_link_paths ( link_paths, opencv. link_paths , None ) ) ;
244
+ cargo_metadata. extend ( Self :: process_link_paths (
245
+ link_paths,
246
+ opencv
247
+ . link_paths
248
+ . into_iter ( )
249
+ . map ( |p| LinkSearch ( Linkage :: Default , p) )
250
+ . collect ( ) ,
251
+ ) ) ;
270
252
if link_paths. map_or ( true , |link_paths| link_paths. is_extend ( ) ) {
271
- cargo_metadata. extend ( Self :: process_link_paths ( None , opencv. framework_paths , Some ( "framework" ) ) ) ;
253
+ cargo_metadata. extend ( Self :: process_link_paths (
254
+ None ,
255
+ opencv
256
+ . framework_paths
257
+ . into_iter ( )
258
+ . map ( |p| LinkSearch ( Linkage :: Framework , p) )
259
+ . collect ( ) ,
260
+ ) ) ;
272
261
}
273
262
274
- cargo_metadata. extend ( Self :: process_link_libs ( link_libs, opencv. libs , None ) ) ;
263
+ cargo_metadata. extend ( Self :: process_link_libs (
264
+ link_libs,
265
+ opencv. libs . into_iter ( ) . map ( |l| LinkLib ( Linkage :: Default , l) ) . collect ( ) ,
266
+ ) ) ;
275
267
if link_libs. map_or ( false , |link_libs| link_libs. is_extend ( ) ) {
276
- cargo_metadata. extend ( Self :: process_link_libs ( None , opencv. frameworks , Some ( "framework" ) ) ) ;
268
+ cargo_metadata. extend ( Self :: process_link_libs (
269
+ None ,
270
+ opencv
271
+ . frameworks
272
+ . into_iter ( )
273
+ . map ( |f| LinkLib ( Linkage :: Framework , f) )
274
+ . collect ( ) ,
275
+ ) ) ;
277
276
}
278
277
279
278
let include_paths = Self :: process_env_var_list ( include_paths, opencv. include_paths ) ;
@@ -326,8 +325,8 @@ impl Library {
326
325
}
327
326
328
327
let mut cargo_metadata = Vec :: with_capacity ( probe_result. link_paths . len ( ) + probe_result. link_libs . len ( ) ) ;
329
- cargo_metadata. extend ( Self :: process_link_paths ( link_paths, probe_result. link_paths , None ) ) ;
330
- cargo_metadata. extend ( Self :: process_link_libs ( link_libs, probe_result. link_libs , None ) ) ;
328
+ cargo_metadata. extend ( Self :: process_link_paths ( link_paths, probe_result. link_paths ) ) ;
329
+ cargo_metadata. extend ( Self :: process_link_libs ( link_libs, probe_result. link_libs ) ) ;
331
330
332
331
Ok ( Self {
333
332
include_paths : Self :: process_env_var_list ( include_paths, probe_result. include_paths ) ,
@@ -367,12 +366,12 @@ impl Library {
367
366
if link_paths. as_ref ( ) . map_or ( false , |lp| !lp. is_extend ( ) ) {
368
367
cargo_metadata. retain ( |p| !p. starts_with ( "cargo:rustc-link-search=" ) ) ;
369
368
}
370
- cargo_metadata. extend ( Self :: process_link_paths ( link_paths, vec ! [ ] , None ) ) ;
369
+ cargo_metadata. extend ( Self :: process_link_paths ( link_paths, vec ! [ ] ) ) ;
371
370
372
371
if link_libs. as_ref ( ) . map_or ( false , |ll| !ll. is_extend ( ) ) {
373
372
cargo_metadata. retain ( |p| !p. starts_with ( "cargo:rustc-link-lib=" ) ) ;
374
373
}
375
- cargo_metadata. extend ( Self :: process_link_libs ( link_libs, vec ! [ ] , None ) ) ;
374
+ cargo_metadata. extend ( Self :: process_link_libs ( link_libs, vec ! [ ] ) ) ;
376
375
377
376
Ok ( Self {
378
377
include_paths,
0 commit comments