@@ -163,6 +163,11 @@ fn fetch() -> io::Result<()> {
163163 let _ = std:: fs:: remove_dir_all ( output_base_path. join ( & clone_dest_dir) ) ;
164164 let status = Command :: new ( "git" )
165165 . current_dir ( & output_base_path)
166+ . args ( if cfg ! ( target_os = "windows" ) {
167+ vec ! [ "-c" , "core.autocrlf=false" ]
168+ } else {
169+ vec ! [ ]
170+ } )
166171 . arg ( "clone" )
167172 . arg ( "--depth=1" )
168173 . arg ( "-b" )
@@ -243,13 +248,49 @@ fn find_sysroot() -> Option<String> {
243248
244249fn build ( sysroot : Option < & str > ) -> io:: Result < ( ) > {
245250 let source_dir = source ( ) ;
251+ if cfg ! ( target_os = "windows" ) {
252+ let path = env:: var ( "PATH" ) . unwrap_or_default ( ) ;
253+ let mut paths = env:: split_paths ( & path) . collect :: < Vec < _ > > ( ) ;
254+ paths. push ( source_dir. clone ( ) ) ;
255+ let new_path = env:: join_paths ( paths) . unwrap ( ) ;
256+
257+ let include = env:: var ( "INCLUDE" ) . unwrap_or_default ( ) ;
258+ let mut includes = env:: split_paths ( & include) . collect :: < Vec < _ > > ( ) ;
259+ includes. push ( source_dir. clone ( ) ) ;
260+ let new_include = env:: join_paths ( includes) . unwrap ( ) ;
261+
262+ env:: set_var ( "PATH" , & new_path) ;
263+ env:: set_var ( "INCLUDE" , & new_include) ;
264+ }
246265
247266 // Command's path is not relative to command's current_dir
248267 let configure_path = source_dir. join ( "configure" ) ;
249268 assert ! ( configure_path. exists( ) ) ;
250- let mut configure = Command :: new ( & configure_path) ;
251- configure. current_dir ( & source_dir) ;
269+ let mut configure = if cfg ! ( target_os = "windows" ) {
270+ if Command :: new ( "sh" )
271+ . arg ( "-c" )
272+ . arg ( "echo ok" )
273+ . output ( )
274+ . is_err ( )
275+ {
276+ return Err ( io:: Error :: new (
277+ io:: ErrorKind :: Other ,
278+ "Failed to find 'sh.exe', which is required for building FFmpeg" ,
279+ ) ) ;
280+ }
281+
282+ let mut configure = Command :: new ( "sh" ) ;
283+ configure. arg ( configure_path) ;
284+ if cfg ! ( target_env = "msvc" ) {
285+ configure. arg ( "--toolchain=msvc" ) ;
286+ }
252287
288+ configure
289+ } else {
290+ Command :: new ( & configure_path)
291+ } ;
292+
293+ configure. current_dir ( & source_dir) ;
253294 configure. arg ( format ! ( "--prefix={}" , search( ) . to_string_lossy( ) ) ) ;
254295
255296 let target = env:: var ( "TARGET" ) . unwrap ( ) ;
@@ -292,6 +333,19 @@ fn build(sysroot: Option<&str>) -> io::Result<()> {
292333 configure. arg ( "--extra-cflags=-march=native -mtune=native" ) ;
293334 }
294335
336+ if env:: var ( "CARGO_CFG_TARGET_OS" ) . as_deref ( ) == Ok ( "windows" ) {
337+ // essential librareis on windowsw
338+ println ! ( "cargo:rustc-link-lib=dylib=ole32" ) ;
339+ println ! ( "cargo:rustc-link-lib=dylib=oleaut32" ) ;
340+ println ! ( "cargo:rustc-link-lib=dylib=gdi32" ) ;
341+ println ! ( "cargo:rustc-link-lib=dylib=user32" ) ;
342+ println ! ( "cargo:rustc-link-lib=dylib=vfw32" ) ;
343+ println ! ( "cargo:rustc-link-lib=dylib=strmiids" ) ;
344+ println ! ( "cargo:rustc-link-lib=dylib=bcrypt" ) ;
345+ println ! ( "cargo:rustc-link-lib=dylib=shlwapi" ) ;
346+ println ! ( "cargo:rustc-link-lib=dylib=shell32" ) ;
347+ }
348+
295349 // for ios it is required to provide sysroot for both configure and bindgen
296350 // for macos the easiest way is to run xcrun, for other platform we support $SYSROOT var
297351 if env:: var ( "CARGO_CFG_TARGET_OS" ) . as_deref ( ) == Ok ( "ios" ) {
@@ -368,7 +422,11 @@ fn build(sysroot: Option<&str>) -> io::Result<()> {
368422 // make it static
369423 configure. arg ( "--enable-static" ) ;
370424 configure. arg ( "--disable-shared" ) ;
371- configure. arg ( "--enable-pthreads" ) ;
425+ // windows includes threading in the standard library
426+ #[ cfg( not( target_env = "msvc" ) ) ]
427+ {
428+ configure. arg ( "--enable-pthreads" ) ;
429+ }
372430
373431 // position independent code
374432 configure. arg ( "--enable-pic" ) ;
0 commit comments