zmwangx / rust-ffmpeg-sys

FFmpeg bindings for Rust.
125 stars 86 forks source link

Add vcpkg support on windows #2

Closed 0xd34d10cc closed 4 years ago

0xd34d10cc commented 4 years ago

Build steps:

  1. install llvm (required for bindgen)
  2. install vcpkg
  3. install ffmpeg via vcpkg: $ vcpkg install ffmpeg:x64-windows-static-md for static libraries, enable "static" feature for ffmpeg-sys $ vcpkg install ffmpeg:x64-windows for dlls, define VCPKGRS_DYNAMIC environment variable See this section of vcpkg-rs docs for more info on static vs dynamic linkage.
  4. run cargo build
zmwangx commented 4 years ago

Hey, thanks for the PR, for some reason I unwatched this repo at some point and as a result was never notified. I'll hopefully try this very soon and merge it if it works for me.

zmwangx commented 4 years ago

I finally tried this. It's pretty nice to be able to build against a managed FFmpeg installation, rather than an ad-hoc one. I would have considered this the goto method, such a shame that vcpkg's FFmpeg is on 4.2, one year out of date...

Two things:

  1. I'd rather have VCPKGRS_DYNAMIC set automatically, since the presence of static or lack thereof is a clear enough signal of intent. So something like
diff --git a/build.rs b/build.rs
index 32cf00f..a81c14b 100644
--- a/build.rs
+++ b/build.rs
@@ -350,7 +350,10 @@ fn try_vcpkg() -> Option<Vec<PathBuf>> {
 }

 #[cfg(target_env = "msvc")]
-fn try_vcpkg() -> Option<Vec<PathBuf>> {
+fn try_vcpkg(statik: bool) -> Option<Vec<PathBuf>> {
+    if !statik {
+        env::set_var("VCPKGRS_DYNAMIC", "1");
+    }
     vcpkg::find_package("ffmpeg")
         .map_err(|e| {
             println!("Could not find ffmpeg with vcpkg: {}", e);
@@ -612,16 +615,7 @@ fn main() {
         );
         link_to_libraries(statik);
         vec![ffmpeg_dir.join("include")]
-    } else if let Some(paths) = try_vcpkg() {
-        let is_vcpkg_static = env::var_os("VCPKGRS_DYNAMIC").is_none();
-        if is_vcpkg_static != statik {
-            panic!(
-                "vcpkg settings do not match ffmpeg-sys settings: VCPKGRS_DYNAMIC is {}, but ffmpeg-sys static feature is {}",
-                if is_vcpkg_static { "not defined, which means that vcpkg libraries are linked statically" } else { "defined" },
-                if statik { "specified" } else { "not specified "}
-            );
-        }
-
+    } else if let Some(paths) = try_vcpkg(statik) {
         // vcpkg doesn't detect the "system" dependencies
         if statik {
             if cfg!(feature = "avcodec") || cfg!(feature = "avdevice") {
  1. (I'm a Unix guy with a Windows machine on the side but little to no knowledge of Windows development, so please bear with me.) I tried static linking and it works well. But I couldn't get dynamic linking to work.

Consider building an example program from zmwangx/rust-ffmpeg:

cargo build --no-default-features --features ffmpeg42,codec,format --example metadata

Now when I execute .\target\debug\examples\metadata I get -1073741515 STATUS_DLL_NOT_FOUND. And Dependency Walker says I'm missing a whole bunch of DLLs, including AVCODEC, AVFORMAT and AVUTIL.

image

Any idea what's going wrong here? My Rust toolchain:

$ rustup show
Default host: x86_64-pc-windows-msvc
rustup home:  C:\Users\zmwang\.rustup

stable-x86_64-pc-windows-msvc (default)
rustc 1.45.1 (c367798cf 2020-07-26)
0xd34d10cc commented 4 years ago
  1. Makes sense.
  2. The problem is that vcpkg installed libraries are not in PATH. To make your example work you'll have to add $VCPKG_ROOT/installed/x64-windows/debug/bin and $VCPKG_ROOT/installed/x64-windows/bin to PATH or just copy dlls manually to the directory in which your executable is located.
zmwangx commented 4 years ago

Cool, thanks. Squashed and merged in b80ddfc.

zmwangx commented 4 years ago

Released v4.3.3 for this.