@@ -3,7 +3,10 @@ use bindgen::{callbacks, Bindings};
33use camino:: Utf8Path as Path ;
44use camino:: Utf8PathBuf as PathBuf ;
55use once_cell:: sync:: Lazy ;
6- use std:: { collections:: HashSet , env, fs} ;
6+ use std:: {
7+ collections:: { HashMap , HashSet } ,
8+ env, fs,
9+ } ;
710
811/// All the libs that FFmpeg has
912static LIBS : Lazy < [ & str ; 7 ] > = Lazy :: new ( || {
@@ -18,6 +21,38 @@ static LIBS: Lazy<[&str; 7]> = Lazy::new(|| {
1821 ]
1922} ) ;
2023
24+ static SYS_STATIC_LIBS : Lazy < HashMap < & str , Vec < & str > > > = Lazy :: new ( || {
25+ if cfg ! ( target_os = "windows" ) {
26+ // Statically linking FFmpeg on Windows requires additional dependencies. This is a map
27+ // of FFmpeg library name to system libraries. In the future, if
28+ // https://github.com/CCExtractor/rusty_ffmpeg/issues/128 is addressed, we will want to
29+ // selectively choose which system libraries to link based on chosen FFmpeg features.
30+ //
31+ // Note that the values were obtained by building FFmpeg using vcpkg with the
32+ // x64-windows-static triplet, and then examining the generated .pc files in the pkgconfig
33+ // directory.
34+ HashMap :: from ( [
35+ (
36+ "avcodec" ,
37+ vec ! [ "mfuuid" , "ole32" , "strmiids" , "ole32" , "user32" ] ,
38+ ) ,
39+ (
40+ "avdevice" ,
41+ vec ! [
42+ "psapi" , "ole32" , "strmiids" , "uuid" , "oleaut32" , "shlwapi" , "gdi32" , "vfw32" ,
43+ ] ,
44+ ) ,
45+ ( "avfilter" , vec ! [ ] ) ,
46+ ( "avformat" , vec ! [ "secur32" , "ws2_32" ] ) ,
47+ ( "avutil" , vec ! [ "user32" , "bcrypt" ] ) ,
48+ ( "swresample" , vec ! [ ] ) ,
49+ ( "swscale" , vec ! [ ] ) ,
50+ ] )
51+ } else {
52+ HashMap :: new ( )
53+ }
54+ } ) ;
55+
2156/// Whitelist of the headers we want to generate bindings
2257static HEADERS : Lazy < Vec < PathBuf > > = Lazy :: new ( || {
2358 [
@@ -399,6 +434,16 @@ fn dynamic_linking(env_vars: &EnvVars) {
399434fn static_linking ( env_vars : & EnvVars ) {
400435 let output_binding_path = & env_vars. out_dir . as_ref ( ) . unwrap ( ) . join ( "binding.rs" ) ;
401436
437+ fn static_link_sys_libs ( ) {
438+ // Statically linking to FFmpeg may also require us to link to some system libraries.
439+ let mut sys_libs: Vec < _ > = SYS_STATIC_LIBS . values ( ) . flatten ( ) . collect ( ) ;
440+ sys_libs. sort ( ) ;
441+ sys_libs. dedup ( ) ;
442+ for sys_lib in sys_libs {
443+ println ! ( "cargo:rustc-link-lib={sys_lib}" ) ;
444+ }
445+ }
446+
402447 #[ cfg( not( target_os = "windows" ) ) ]
403448 {
404449 fn static_linking_with_pkg_config_and_bindgen (
@@ -419,6 +464,7 @@ fn static_linking(env_vars: &EnvVars) {
419464 . write_to_file ( output_binding_path)
420465 . expect ( "Cannot write binding to file." ) ;
421466 }
467+ static_link_sys_libs ( ) ;
422468 Ok ( ( ) )
423469 }
424470 // Hint: set PKG_CONFIG_PATH to some placeholder value will let pkg_config probing system library.
@@ -491,6 +537,7 @@ Enable `link_vcpkg_ffmpeg` feature if you want to link ffmpeg libraries installe
491537 {
492538 if let Some ( ffmpeg_libs_dir) = env_vars. ffmpeg_libs_dir . as_ref ( ) {
493539 static_linking_with_libs_dir ( & * LIBS , ffmpeg_libs_dir) ;
540+ static_link_sys_libs ( ) ;
494541 if let Some ( ffmpeg_binding_path) = env_vars. ffmpeg_binding_path . as_ref ( ) {
495542 use_prebuilt_binding ( ffmpeg_binding_path, output_binding_path) ;
496543 } else if let Some ( ffmpeg_include_dir) = env_vars. ffmpeg_include_dir . as_ref ( ) {
0 commit comments