erickt / rust-zmq

Rust zeromq bindings.
Apache License 2.0
887 stars 189 forks source link

Compiling rust-zmq on windows using vcpkg version of libzmq #282

Open vegapit opened 4 years ago

vegapit commented 4 years ago

Hello

This is not a bug report but a short note to describe how to compile a project using the rust-zmq crate on Windows 10 with cargo. It ended up being easy but took me a while to figure out so I thought I would share:

  1. Install vcpkg: instructions on https://github.com/microsoft/vcpkg
  2. Install zeromq usign vcpkg: vcpkg install zeromq
  3. Create a copy called zmq.lib of the libzmq-mt-.lib file created your path\to\vcpkg\installed\x64-windows\lib* directory
  4. Create an environment variable called LIBZMQ_PREFIX pointing to path\to\vcpkg\installed\x64-windows

You can now build your project using rust-zmq using cargo.

P.S: I am using an x64 environment, if you are not, you will probably have to readjust the path to the vcpkg libraries mentioned above

rotty commented 4 years ago

Thanks for the info! This is bound to be useful for Windows users, and I'll try to incorporate it into the README.

Since it seems vcpkg works nicely for zeromq, it would make sense to support vcpkg directly, using the vcpkg crate, similar to how we use pkg-config via the metadeps crate on Unixoids. The openssl crate does this; see this PR. This would avoid the need for steps 3 and 4 above, and make installation seamless.

Would you be interested in giving implementing direct vcpkg support a try? I cannot help much with that, as I don't have private access to Windows environment, but I'd try to mentor/review.

vegapit commented 4 years ago

I am happy to give it a try, not a problem. I will have a look at the vcpkg crate. In the meantime, if you already have an idea as to what steps need to be implemented to make it all work, please let me know.

rotty commented 4 years ago

The code to touch would be configure in zmq-sys/build/pkg_config.rs. The new code could be adapted from the openssl crate, see openssl-sys/build/find_normal.rs. I'd appreciate it if you would find a way to avoid the process::exit(0) calls, though -- this should be handled via by using conditional compilation:

 #[cfg(not(target_env = "msvc"))
fn probe() -> Result<(), String> {
  metadeps.probe().map_err(String::to_string)
}

The MSVC implementation is left as an exercise to the reader :-).

vegapit commented 4 years ago

Ok, I have a little concern. See this note from the vcpkg crate:

You must set one of RUSTFLAGS=-Ctarget-feature=+crt-static or VCPKGRS_DYNAMIC=1 in your environment or the vcpkg-rs helper will not find any libraries. If VCPKGRS_DYNAMIC is set, cargo install will generate dynamically linked binaries, in which case you will have to arrange for dlls from your Vcpkg installation to be available in your path.

Do you think it is possible to find libzmq without the user having to set any env var? I tried using std::env::set_var before calling vcpkg::find_package but no luck so far.

vegapit commented 4 years ago

Ok, this piece of code works, but as you can see I need to enter the full library name libzmq-mt-4_3_2 for it to work. vcpkg fails to find the generic libzmq stem.

#[cfg(target_env = "msvc")]
pub fn probe() -> Result<(), String> {

    env::set_var("VCPKGRS_DYNAMIC","1");

    let lib = vcpkg::Config::new()
        .emit_includes(true)
        .lib_name("libzmq-mt-4_3_2")
        .find_package("zmq");

    match lib {
        Ok(_) => {
            println!("cargo:rustc-link-lib=libzmq-mt-4_3_2");
            Ok(())
        },
        Err(e) => {
            panic!( "vcpkg link error: {}", e )
        }
    }
}
jean-airoldie commented 4 years ago

@vegapit Does the vendored flag not work for windows? It would automatically link against a static libzmq+4.3.2 lib.

vegapit commented 4 years ago

@jean-airoldie I am afraid I do not know what the vendored flag is. If you think of anything specific I can try, let me know.

jean-airoldie commented 4 years ago

I meant the vendored feature flag (features = ['vendored']). This compiles zeromq from source using cmake. The only dependency is cmake.

https://github.com/erickt/rust-zmq/blob/master/Cargo.toml#L28

vegapit commented 4 years ago

It works indeed. Thanks for pointing the feature out. I guess this makes the vcpkg support unnecessary?

jean-airoldie commented 4 years ago

The vendored feature is pretty new. I PRd it not so long ago when I wrote my libzmq-rs crate. I guess vcpkg is more of a backward compat thing now.

rotty commented 4 years ago

Uh, I completetly forgot to mention the vendored feature, which indeed is the most painless way of getting zmq installed, especially on Windows. Thanks for chiming in, @jean-airoldie. Since vcpkg doesn't gain much over manual installation (steps (3) and (4) still necessary, it seems), I propose the following for now:

Stargateur commented 4 years ago

AFAICT, the renaming step isn't necessary when using the openssl with vcpkg, so one should look into if and how that's possible. Perhaps this even is an issue in how libzmq's vcpkg support is setup.

That unfortunate that libzmq-mt-4_3_3 is not parsed by pkg-config.

Anyway, thanks a lot for the tip, I don't work a lot on windows but having a way to build my project on windows is a big plus.

WestXu commented 2 years ago

Any tips on building it using Github Actions on windows?

I do find an action of vcpkg but have no clue how to use it to compile this.