OpenSSL pre-installed version bundling

bf9rczko2uq9's Avatar

bf9rczko2uq9

10 May, 2018 05:13 PM

Hello,

First off, thank you for the great service.

Have been struggling with bundling the pre-installed OpenSSL library in an Appveyor built application. Can build the app fine and bundle the .dlls from the version used to built with, but when distributed to client machines without OpenSSL and the MSVC runtimes it uses, MSVC120, the app fails to load with missing dependencies.

Dependency walker then points to the missing MSVCR120.dll dependency of the bundled libeay32.dll.

The same issue occurs whether linking to libeay32MD or libeay32MT non-static libraries, which is not what I had expected.

The libeay32MT version under \VC\lib\ is supposed to be statically linked to the MSVC runtimes but not a static library itself, right? But when using /MD for dynamic linking to the statically linked libeay32MT in order to not have to bundle MSVC runtimes, which means having to ship the .dll along with the application, the dll itself requires the runtime. Have not found any different pre-installed versions of the dlls that are statically linked.

The only solution I have found so far is to ship the .dlls from the binary packages at https://indy.fulgan.com/SSL/ with the application which are statically linked and dependency walker confirms no MSVC runtime dependency.

With these .dlls and the application linked against libeay32MD from the pre-installed OpenSSL on appveyor, everything works fine without shipping MSVC runtimes. This would not be an issue in itself, but the MSVC runtimes on appveyor are not distributable and in turn depend on windows features that are version specific..

Ideally though would like to only use the pre-installed OpenSSL so do not have to keep updating the version used for bundling, which may also be different than the libraries used when building.

Are there any suggestions? Anyone else with a similar requirement that has solved it another way?

For reference, here are build artifacts for the two cases:
 libeay32MD linked, dlls from pre-installed: https://ci.appveyor.com/project/pkittenis/ssh2-python/build/1.0.487/job/ixs0aub32gx2p2u4/artifacts
libeaye32MD linked, dlls from fulgan: https://ci.appveyor.com/project/pkittenis/ssh2-python/build/job/tvxxypns75jsgosb/artifacts

Examining the, for example, ssh2/session.pyd in the artifact file with dependency walker confirms the missing MSVC dependency in the former. The .whl files are zip archives - it's a python binary distributable format for a python library.

Here are dependency walker screenshots of the bundled application for the two cases.

With Appveyor shipped dlls: ssh2-python_msvc_dep.png

With fulgan dlls: ssh-python_no_msvc.png

Thank you.

  1. Support Staff 1 Posted by Owen McDonnell on 11 May, 2018 05:21 AM

    Owen McDonnell's Avatar

    I'm not a C++ dev so pardon my ignorance, but I'm trying to understand this paragraph,

    
    The libeay32MT version under \VC\lib\ is supposed to be statically linked to the MSVC runtimes but not a static library itself, right? But
    when using /MD for dynamic linking to the statically linked libeay32MT in order to not have to bundle MSVC runtimes, which means
    having to ship the .dll along with the application, the dll itself requires the runtime. Have not found any different pre-installed versions of
    the dlls that are statically linked.
    
    My understanding is that /MD flag links to runtime with dependency on msvcr<versionNumber>.dll whereas /MT flag is conventional static linking. So isn't it the latter flag that you want here?
  2. 2 Posted by bf9rczko2uq9 on 11 May, 2018 11:10 AM

    bf9rczko2uq9's Avatar

    No, that's not right. /MD is a compiler flag which tells it to make a dynamically loadable module, whereas /MT tells it to create a static library.

    That has nothing to do with how the C/C++ runtimes were linked, which is done by linker not compiler and can be either statically or dynamically.

    So in essence can build either static libraries (/MT) or dynamic libraries (/MD) which are linked either statically or dynamically to their C/C++ runtimes for a total of 8 permutations.

    This is why there are 8 versions of the openssl libraries, two dynamic libraries, libeay32MD and libeay32MT, referring to dynamic or static linking to MSVC runtimes, and static/libeay32MT, static/libeay32MD for static library of the same. static/libeay32MD is a static library with dynamic linking to MSVC runtimes which in some scenarios is preferred.

    In this case only building a dynamic library is an option as it is a library to be loaded into application, not a stand alone program. So /MD compiler flag with dynamic openssl libraries is the only option. The use case does require static links to MSVC runtimes, however, so as not to require the user to install them.

    To do that, the library was set to link against the dynamic libeay32MT. As they are dynamically loaded, they require that the .dlls are shipped. See build output: https://ci.appveyor.com/project/pkittenis/ssh2-python/build/job/0k7qs75gwn8fkg9f

    The issue as far as I can see is that the dynamic libeay32MT versions of the library are lacking their equivalent statically linked with MSVC runtimes .dlls to distribute with. libeay32MT does not require MSVC runtimes but the dlls do, making the *eay32MT libraries moot. These dlls are available in other binary distributions ( https://indy.fulgan.com/SSL), but not in the pre-installed appveyor openssl.

  3. 3 Posted by bf9rczko2uq9 on 11 May, 2018 11:15 AM

    bf9rczko2uq9's Avatar

    For reference, the env variable or cmake flag to link with static MSVC runtimes is OPENSSL_MSVC_STATIC_RT. This in turn compiles against *eay32MT. It is separate from OPENSSL_USE_STATIC_LIBS which will compile against static/<..>.

    See https://cmake.org/cmake/help/v3.10/module/FindOpenSSL.html

  4. 4 Posted by bf9rczko2uq9 on 14 May, 2018 02:12 PM

    bf9rczko2uq9's Avatar

    Should also point out that linking against static MT libraries but compiling with /MD for a dynamic library is also not an option.

    That requires that the same compiler was used for both the library to be linked as well as the dynamic library or the MSVC run times will not match, resulting in errors.

    Unfortunately the only option, other than downloading statically linked dlls from another distribution, is to build OpenSSL on every job with multiple compilers - not a very attractive option to say the least.

  5. Support Staff 5 Posted by Owen McDonnell on 14 May, 2018 05:32 PM

    Owen McDonnell's Avatar

    Again, apologies for not having too much experience with the subtleties of c++ static/dynamic linking. But, if you'll indulge me, I've a simple question... What is the difference between the 'libeay32.dll' at C:\OpenSSL-Win32 on the AppVeyor build image and the one of the same name in the binary distributions you linked to?

  6. 6 Posted by bf9rczko2uq9 on 15 May, 2018 08:44 AM

    bf9rczko2uq9's Avatar

    No worries, not too familiar with these windows specifics either.

    The difference is the ones in C:\OpenSSL-Win32 are linked dynamically with MSVC run times meaning they require the MSVC dlls where as the ones from the other binary distribution are linked statically and do not.

    Have attached dependency walker screenshots for each with the openssl dll dependencies circled. The one from appveyor has a dependency on msvcr120.dll whereas the other does not.

Reply to this discussion

Internal reply

Formatting help / Preview (switch to plain text) No formatting (switch to Markdown)

Attaching KB article:

»

Already uploaded files

  • ssh-python_no_msvc.png 32.4 KB
  • ssh2-python_msvc_dep.png 26.4 KB

Attached Files

You can attach files up to 10MB

If you don't have an account yet, we need to confirm you're human and not a machine trying to post spam.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac