@@ -242,18 +242,28 @@ fn generate_bindings(ffmpeg_include_dir: &Path, headers: &[PathBuf]) -> Bindings
242242 . expect ( "Binding generation failed." )
243243}
244244
245- fn static_linking_with_libs_dir ( library_names : & [ & str ] , ffmpeg_libs_dir : & Path ) {
245+ fn linking_with_libs_dir ( library_names : & [ & str ] , ffmpeg_libs_dir : & Path , mode : FfmpegLinkMode ) {
246246 println ! ( "cargo:rustc-link-search=native={}" , ffmpeg_libs_dir) ;
247247 for library_name in library_names {
248- println ! ( "cargo:rustc-link-lib=static={}" , library_name) ;
248+ println ! ( "cargo:rustc-link-lib={}={}" , library_name, match mode {
249+ FfmpegLinkMode :: Dynamic => "dylib" ,
250+ FfmpegLinkMode :: Static => "static" ,
251+ } ) ;
249252 }
250253}
251254
255+ #[ derive( Clone , Copy ) ]
256+ enum FfmpegLinkMode {
257+ Static ,
258+ Dynamic ,
259+ }
260+
252261#[ allow( dead_code) ]
253262pub struct EnvVars {
254263 docs_rs : Option < String > ,
255264 out_dir : Option < PathBuf > ,
256265 ffmpeg_include_dir : Option < PathBuf > ,
266+ ffmpeg_link_mode : Option < FfmpegLinkMode > ,
257267 ffmpeg_dll_path : Option < PathBuf > ,
258268 ffmpeg_pkg_config_path : Option < PathBuf > ,
259269 ffmpeg_libs_dir : Option < PathBuf > ,
@@ -277,6 +287,12 @@ impl EnvVars {
277287 ffmpeg_pkg_config_path : env:: var ( "FFMPEG_PKG_CONFIG_PATH" ) . ok ( ) . map ( remove_verbatim) ,
278288 ffmpeg_libs_dir : env:: var ( "FFMPEG_LIBS_DIR" ) . ok ( ) . map ( remove_verbatim) ,
279289 ffmpeg_binding_path : env:: var ( "FFMPEG_BINDING_PATH" ) . ok ( ) . map ( remove_verbatim) ,
290+ ffmpeg_link_mode : match env:: var ( "FFMPEG_LINK_MODE" ) . ok ( ) . as_deref ( ) {
291+ Some ( "static" ) => Some ( FfmpegLinkMode :: Static ) ,
292+ Some ( "dynamic" ) => Some ( FfmpegLinkMode :: Dynamic ) ,
293+ Some ( r) => panic ! ( "invalid FFMPEG_LINK_MODE value {r}, expected [static,dynamic]" ) ,
294+ None => None ,
295+ }
280296 }
281297 }
282298}
@@ -359,8 +375,18 @@ mod vcpkg_linking {
359375 }
360376}
361377
362- fn dynamic_linking ( env_vars : & EnvVars ) {
378+ fn dynamic_linking ( mut env_vars : EnvVars ) {
363379 let ffmpeg_dll_path = env_vars. ffmpeg_dll_path . as_ref ( ) . unwrap ( ) ;
380+ if ffmpeg_dll_path. is_dir ( ) {
381+ if env_vars. ffmpeg_libs_dir . is_none ( ) {
382+ env_vars. ffmpeg_libs_dir = Some ( ffmpeg_dll_path. clone ( ) ) ;
383+ }
384+ if env_vars. ffmpeg_link_mode . is_none ( ) {
385+ env_vars. ffmpeg_link_mode = Some ( FfmpegLinkMode :: Dynamic ) ;
386+ }
387+
388+ return linking ( env_vars) ;
389+ }
364390
365391 let output_binding_path = & env_vars. out_dir . as_ref ( ) . unwrap ( ) . join ( "binding.rs" ) ;
366392
@@ -396,12 +422,12 @@ fn dynamic_linking(env_vars: &EnvVars) {
396422 }
397423}
398424
399- fn static_linking ( env_vars : & EnvVars ) {
425+ fn linking ( env_vars : EnvVars ) {
400426 let output_binding_path = & env_vars. out_dir . as_ref ( ) . unwrap ( ) . join ( "binding.rs" ) ;
401427
402428 #[ cfg( not( target_os = "windows" ) ) ]
403429 {
404- fn static_linking_with_pkg_config_and_bindgen (
430+ fn linking_with_pkg_config_and_bindgen (
405431 env_vars : & EnvVars ,
406432 output_binding_path : & Path ,
407433 ) -> Result < ( ) , pkg_config:: Error > {
@@ -430,10 +456,10 @@ fn static_linking(env_vars: &EnvVars) {
430456 ) ;
431457 }
432458 env:: set_var ( "PKG_CONFIG_PATH" , ffmpeg_pkg_config_path) ;
433- static_linking_with_pkg_config_and_bindgen ( env_vars, output_binding_path)
459+ linking_with_pkg_config_and_bindgen ( & env_vars, output_binding_path)
434460 . expect ( "Static linking with pkg-config failed." ) ;
435461 } else if let Some ( ffmpeg_libs_dir) = env_vars. ffmpeg_libs_dir . as_ref ( ) {
436- static_linking_with_libs_dir ( & * LIBS , ffmpeg_libs_dir) ;
462+ linking_with_libs_dir ( & * LIBS , ffmpeg_libs_dir, env_vars . ffmpeg_link_mode . unwrap_or ( FfmpegLinkMode :: Static ) ) ;
437463 if let Some ( ffmpeg_binding_path) = env_vars. ffmpeg_binding_path . as_ref ( ) {
438464 use_prebuilt_binding ( ffmpeg_binding_path, output_binding_path) ;
439465 } else if let Some ( ffmpeg_include_dir) = env_vars. ffmpeg_include_dir . as_ref ( ) {
@@ -460,7 +486,7 @@ Enable `link_vcpkg_ffmpeg` feature if you want to link ffmpeg libraries installe
460486 #[ cfg( feature = "link_system_ffmpeg" ) ]
461487 if !success {
462488 if let Err ( e) =
463- static_linking_with_pkg_config_and_bindgen ( env_vars, output_binding_path)
489+ linking_with_pkg_config_and_bindgen ( env_vars, output_binding_path)
464490 {
465491 error. push ( '\n' ) ;
466492 error. push_str ( & format ! ( "Link system FFmpeg failed: {:?}" , e) ) ;
@@ -490,7 +516,7 @@ Enable `link_vcpkg_ffmpeg` feature if you want to link ffmpeg libraries installe
490516 #[ cfg( target_os = "windows" ) ]
491517 {
492518 if let Some ( ffmpeg_libs_dir) = env_vars. ffmpeg_libs_dir . as_ref ( ) {
493- static_linking_with_libs_dir ( & * LIBS , ffmpeg_libs_dir) ;
519+ linking_with_libs_dir ( & * LIBS , ffmpeg_libs_dir, env_vars . ffmpeg_link_mode ) ;
494520 if let Some ( ffmpeg_binding_path) = env_vars. ffmpeg_binding_path . as_ref ( ) {
495521 use_prebuilt_binding ( ffmpeg_binding_path, output_binding_path) ;
496522 } else if let Some ( ffmpeg_include_dir) = env_vars. ffmpeg_include_dir . as_ref ( ) {
@@ -502,7 +528,7 @@ Enable `link_vcpkg_ffmpeg` feature if you want to link ffmpeg libraries installe
502528 }
503529 } else {
504530 #[ cfg( feature = "link_vcpkg_ffmpeg" ) ]
505- vcpkg_linking:: linking_with_vcpkg_and_bindgen ( env_vars , output_binding_path)
531+ vcpkg_linking:: linking_with_vcpkg_and_bindgen ( & zenv_vars , output_binding_path)
506532 . expect ( "Linking FFmpeg with vcpkg failed." ) ;
507533 #[ cfg( not( feature = "link_vcpkg_ffmpeg" ) ) ]
508534 panic ! (
@@ -516,7 +542,7 @@ Enable `link_vcpkg_ffmpeg` feature if you want to link ffmpeg provided by vcpkg.
516542 }
517543}
518544
519- fn docs_rs_linking ( env_vars : & EnvVars ) {
545+ fn docs_rs_linking ( env_vars : EnvVars ) {
520546 // If it's a documentation generation from docs.rs, just copy the bindings
521547 // generated locally to `OUT_DIR`. We do this because the building
522548 // environment of docs.rs doesn't have an network connection, so we cannot
@@ -531,11 +557,11 @@ fn docs_rs_linking(env_vars: &EnvVars) {
531557fn main ( ) {
532558 let env_vars = EnvVars :: init ( ) ;
533559 if env_vars. docs_rs . is_some ( ) {
534- docs_rs_linking ( & env_vars) ;
560+ docs_rs_linking ( env_vars) ;
535561 } else if env_vars. ffmpeg_dll_path . is_some ( ) {
536- dynamic_linking ( & env_vars) ;
562+ dynamic_linking ( env_vars) ;
537563 } else {
538564 // fallback to static linking
539- static_linking ( & env_vars) ;
565+ linking ( env_vars) ;
540566 }
541567}
0 commit comments