sfackler/rust-openssl

windows `vendored` doesn't statically link

Closed this issue · 4 comments

Am using the vendored flag in my project on windows (rust 1.48 stable-x86_64-pc-windows-msvc) and I can't get to statically link the compiled library (doc says that "If the vendored Cargo feature is enabled, the openssl-src crate will be used to compile and statically link to a copy of OpenSSL.").
My cargo toml declares:

openssl = { version = "~0.10.30", features = ["vendored"] }

When I cargo run my app crashes with exit code: 0xc0000135, STATUS_DLL_NOT_FOUND.; a quick check with a dependency checker reveals in fact that the app needs the libcrypto-1_1-x64.dll and libssl-1_1-x64.dll. Both get properly build under target/debug/build/openssl-sys, I can see both the .dll and .lib files, but the libs don't get linked to the executable.

(Note I did use successfully in the past the openssl-sys method, using vcpkg, but I wanted to change to vendored so I could link to the latest version of openssl as I can control my build, but I can't control the installation on the destination system)

The output log from openssl-sys has this at the end

cargo:rustc-link-lib=static=libssl
cargo:rustc-link-lib=static=libcrypto
cargo:rustc-link-lib=dylib=gdi32
cargo:rustc-link-lib=dylib=user32
cargo:rustc-link-lib=dylib=crypt32
cargo:rustc-link-lib=dylib=ws2_32
cargo:rustc-link-lib=dylib=advapi32

but they don't look like they are picked by cargo. Any idea what I should be looking for?

I can reproduce this locally, and it looks like the linker is preferring to link to a dynamically linked OpenSSL in PATH (coming from Strawberry Perl) to the statically built one. I'm not familiar enough with MSVC to know if that's expected or not though.

I've run a cargo -vv on both windows and linux to spot any obvious differences. This gist has the two relevant build logs (formatted for clarity).
The only obvious difference I spot (among the PATH/LD_LIBRARY_PATH changes) is that the windows build has this row when building the openssl library:

    --cfg "osslconf=\"OPENSSL_NO_ENGINE\""

Looking through the code doesn't look like it's impacting?

The difference won't be in the arguments passed to rustc, it will be in the behavior of the linker rustc invokes (link.exe vs cc)

Seems I found the culprit.
This is omitting the no-shared configuration flag on MSVC when it doesn't see a crt-static feature. I'll move this issue there.
Forcing that no-shared argument links correctly the libraries.