@@ -187,6 +187,31 @@ impl callbacks::ParseCallbacks for FilterCargoCallbacks {
187187 }
188188}
189189
190+ #[ derive( Clone , Copy ) ]
191+ enum FFmpegLinkMode {
192+ Static ,
193+ Dynamic ,
194+ }
195+
196+ impl From < String > for FFmpegLinkMode {
197+ fn from ( value : String ) -> Self {
198+ match & * value {
199+ "static" => FFmpegLinkMode :: Static ,
200+ "dynamic" => FFmpegLinkMode :: Dynamic ,
201+ _ => panic ! ( "Invalid FFMPEG_LINK_MODE value, expected [static,dynamic]" ) ,
202+ }
203+ }
204+ }
205+
206+ impl std:: fmt:: Display for FFmpegLinkMode {
207+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
208+ match self {
209+ FFmpegLinkMode :: Static => write ! ( f, "static" ) ,
210+ FFmpegLinkMode :: Dynamic => write ! ( f, "dylib" ) ,
211+ }
212+ }
213+ }
214+
190215fn use_prebuilt_binding ( from : & Path , to : & Path ) {
191216 fs:: copy ( from, to) . expect ( "Prebuilt binding file failed to be copied." ) ;
192217}
@@ -242,31 +267,24 @@ fn generate_bindings(ffmpeg_include_dir: &Path, headers: &[PathBuf]) -> Bindings
242267 . expect ( "Binding generation failed." )
243268}
244269
245- fn linking_with_libs_dir ( library_names : & [ & str ] , ffmpeg_libs_dir : & Path , mode : FfmpegLinkMode ) {
270+ fn linking_with_libs_dir ( library_names : & [ & str ] , ffmpeg_libs_dir : & Path , mode : FFmpegLinkMode ) {
246271 println ! ( "cargo:rustc-link-search=native={ffmpeg_libs_dir}" ) ;
247272 for library_name in library_names {
248- println ! (
249- "cargo:rustc-link-lib={}={library_name}" ,
250- match mode {
251- FfmpegLinkMode :: Dynamic => "dylib" ,
252- FfmpegLinkMode :: Static => "static" ,
253- }
254- ) ;
273+ println ! ( "cargo:rustc-link-lib={mode}={library_name}" ) ;
255274 }
256275}
257276
258- #[ derive( Clone , Copy ) ]
259- enum FfmpegLinkMode {
260- Static ,
261- Dynamic ,
277+ fn linking_with_single_lib ( library_name : & str , ffmpeg_lib_dir : & Path , mode : FFmpegLinkMode ) {
278+ println ! ( "cargo:rustc-link-search=native={ffmpeg_lib_dir}" ) ;
279+ println ! ( "cargo:rustc-link-lib={mode}={library_name}" ) ;
262280}
263281
264282#[ allow( dead_code) ]
265283pub struct EnvVars {
266284 docs_rs : Option < String > ,
267285 out_dir : Option < PathBuf > ,
268286 ffmpeg_include_dir : Option < PathBuf > ,
269- ffmpeg_link_mode : Option < FfmpegLinkMode > ,
287+ ffmpeg_link_mode : Option < FFmpegLinkMode > ,
270288 ffmpeg_dll_path : Option < PathBuf > ,
271289 ffmpeg_pkg_config_path : Option < PathBuf > ,
272290 ffmpeg_libs_dir : Option < PathBuf > ,
@@ -291,12 +309,7 @@ impl EnvVars {
291309 ffmpeg_pkg_config_path : env:: var ( "FFMPEG_PKG_CONFIG_PATH" ) . ok ( ) . map ( remove_verbatim) ,
292310 ffmpeg_libs_dir : env:: var ( "FFMPEG_LIBS_DIR" ) . ok ( ) . map ( remove_verbatim) ,
293311 ffmpeg_binding_path : env:: var ( "FFMPEG_BINDING_PATH" ) . ok ( ) . map ( remove_verbatim) ,
294- ffmpeg_link_mode : match env:: var ( "FFMPEG_LINK_MODE" ) . ok ( ) . as_deref ( ) {
295- Some ( "static" ) => Some ( FfmpegLinkMode :: Static ) ,
296- Some ( "dynamic" ) => Some ( FfmpegLinkMode :: Dynamic ) ,
297- Some ( r) => panic ! ( "invalid FFMPEG_LINK_MODE value {r}, expected [static,dynamic]" ) ,
298- None => None ,
299- } ,
312+ ffmpeg_link_mode : env:: var ( "FFMPEG_LINK_MODE" ) . ok ( ) . map ( Into :: into) ,
300313 }
301314 }
302315}
@@ -379,41 +392,29 @@ mod vcpkg_linking {
379392 }
380393}
381394
382- fn dynamic_linking ( mut env_vars : EnvVars ) {
395+ fn dynamic_linking ( env_vars : EnvVars ) {
383396 let ffmpeg_dll_path = env_vars. ffmpeg_dll_path . as_ref ( ) . unwrap ( ) ;
384397 if ffmpeg_dll_path. is_dir ( ) {
385- if env_vars. ffmpeg_libs_dir . is_none ( ) {
386- env_vars. ffmpeg_libs_dir = Some ( ffmpeg_dll_path. clone ( ) ) ;
387- }
388- if env_vars. ffmpeg_link_mode . is_none ( ) {
389- env_vars. ffmpeg_link_mode = Some ( FfmpegLinkMode :: Dynamic ) ;
390- }
391-
392- return linking ( env_vars) ;
398+ linking_with_libs_dir ( & * LIBS , ffmpeg_dll_path, FFmpegLinkMode :: Dynamic ) ;
399+ } else {
400+ let ( lib_name, ffmpeg_dll_dir) = (
401+ ffmpeg_dll_path
402+ . file_stem ( )
403+ . map ( |stem| {
404+ if cfg ! ( target_os = "windows" ) {
405+ stem
406+ } else {
407+ stem. trim_start_matches ( "lib" )
408+ }
409+ } )
410+ . unwrap ( )
411+ . to_string ( ) ,
412+ ffmpeg_dll_path. parent ( ) . unwrap ( ) . to_path_buf ( ) ,
413+ ) ;
414+ linking_with_single_lib ( & lib_name, & ffmpeg_dll_dir, FFmpegLinkMode :: Dynamic ) ;
393415 }
394416
395417 let output_binding_path = & env_vars. out_dir . as_ref ( ) . unwrap ( ) . join ( "binding.rs" ) ;
396-
397- // Extract dll name and the dir the dll is in.
398- let ( ffmpeg_dll_name, ffmpeg_dll_dir) = {
399- let mut ffmpeg_dll_path = PathBuf :: from ( ffmpeg_dll_path) ;
400- // Without extension.
401- let ffmpeg_dll_filename = ffmpeg_dll_path. file_stem ( ) . unwrap ( ) ;
402- let ffmpeg_dll_name = if cfg ! ( target_os = "windows" ) {
403- ffmpeg_dll_filename
404- } else {
405- ffmpeg_dll_filename. trim_start_matches ( "lib" )
406- }
407- . to_string ( ) ;
408- // Remove file name.
409- ffmpeg_dll_path. pop ( ) ;
410- let ffmpeg_dll_path = ffmpeg_dll_path. to_string ( ) ;
411- ( ffmpeg_dll_name, ffmpeg_dll_path)
412- } ;
413-
414- println ! ( "cargo:rustc-link-lib=dylib={}" , ffmpeg_dll_name) ;
415- println ! ( "cargo:rustc-link-search=native={}" , ffmpeg_dll_dir) ;
416-
417418 if let Some ( ffmpeg_binding_path) = env_vars. ffmpeg_binding_path . as_ref ( ) {
418419 use_prebuilt_binding ( ffmpeg_binding_path, output_binding_path) ;
419420 } else if let Some ( ffmpeg_include_dir) = env_vars. ffmpeg_include_dir . as_ref ( ) {
@@ -466,7 +467,7 @@ fn linking(env_vars: EnvVars) {
466467 linking_with_libs_dir (
467468 & * LIBS ,
468469 ffmpeg_libs_dir,
469- env_vars. ffmpeg_link_mode . unwrap_or ( FfmpegLinkMode :: Static ) ,
470+ env_vars. ffmpeg_link_mode . unwrap_or ( FFmpegLinkMode :: Static ) ,
470471 ) ;
471472 if let Some ( ffmpeg_binding_path) = env_vars. ffmpeg_binding_path . as_ref ( ) {
472473 use_prebuilt_binding ( ffmpeg_binding_path, output_binding_path) ;
@@ -528,7 +529,7 @@ Enable `link_vcpkg_ffmpeg` feature if you want to link ffmpeg libraries installe
528529 linking_with_libs_dir (
529530 & * LIBS ,
530531 ffmpeg_libs_dir,
531- env_vars. ffmpeg_link_mode . unwrap_or ( FfmpegLinkMode :: Static ) ,
532+ env_vars. ffmpeg_link_mode . unwrap_or ( FFmpegLinkMode :: Static ) ,
532533 ) ;
533534 if let Some ( ffmpeg_binding_path) = env_vars. ffmpeg_binding_path . as_ref ( ) {
534535 use_prebuilt_binding ( ffmpeg_binding_path, output_binding_path) ;
@@ -574,7 +575,7 @@ fn main() {
574575 } else if env_vars. ffmpeg_dll_path . is_some ( ) {
575576 dynamic_linking ( env_vars) ;
576577 } else {
577- // fallback to static linking
578+ // fallback to normal linking
578579 linking ( env_vars) ;
579580 }
580581}
0 commit comments