IMPORTED_LOCATION is incorrect for OpenSSL::SSL and OpenSSL::Crypto

Problem Description

I installed OpenSSL using the binaries installer provided by ShiningLight.OpenSSL on Windows. And here is its install location:

C:\Program Files\OpenSSL-Win64

However, I found that the imported targets defined by FindOpenSSL built-in module don’t have correct IMPORTED_LOCATION or IMPORTED_LOCATION_<CONFIG> specified with this version of OpenSSL installed. I used CMakePrintHelpers module to check its values:

include(CMakePrintHelpers)
cmake_print_properties(
    TARGETS 
        OpenSSL::SSL
        OpenSSL::Crypto
    PROPERTIES
        IMPORTED_LOCATION
        IMPORTED_LOCATION_DEBUG
        IMPORTED_LOCATION_RELEASE
)

The result turns out that:

-- 
 Properties for TARGET OpenSSL::SSL:
   OpenSSL::SSL.IMPORTED_LOCATION = <NOTFOUND>
   OpenSSL::SSL.IMPORTED_LOCATION_DEBUG = "C:/Program Files/OpenSSL-Win64/lib/VC/libssl64MDd.lib"
   OpenSSL::SSL.IMPORTED_LOCATION_RELEASE = "C:/Program Files/OpenSSL-Win64/lib/VC/libssl64MD.lib"
 Properties for TARGET OpenSSL::Crypto:
   OpenSSL::Crypto.IMPORTED_LOCATION = <NOTFOUND>
   OpenSSL::Crypto.IMPORTED_LOCATION_DEBUG = "C:/Program Files/OpenSSL-Win64/lib/VC/libcrypto64MDd.lib"
   OpenSSL::Crypto.IMPORTED_LOCATION_RELEASE = "C:/Program Files/OpenSSL-Win64/lib/VC/libcrypto64MD.lib"

As we can see:

  • IMPORTED_LOCATION is empty
  • IMPORTED_LOCATION_<CONFIG> is specified with *.lib instead of *.dll

In my opinions, these two variables should be populated with:

  • OpenSSL::SSL: C:\Program Files\OpenSSL-Win64\bin\libssl-3-x64.dll
  • OpenSSL::Crypto: C:\Program Files\OpenSSL-Win64\bin\libcrypto-3-x64.dll

respectively.

Therefore, I think this is why I failed to use $<TARGET_RUNTIME_DLLS:tgt> regex to copy the runtime dependencies of my executable linked with OpenSSL::SSL and OpenSSL::Crypto:

if (WIN32)
    add_custom_command(
        TARGET ${target_name} POST_BUILD
        COMMAND 
            "${CMAKE_COMMAND}" -E copy -t
            "$<TARGET_RUNTIME_DLLS:${target_name}>"
            "$<TARGET_FILE_DIR:${target_name}>"
        COMMAND_EXPAND_LISTS
    )
endif ()

And the following is the error message caused by not having libcrypto-3-x64.dll and libssl-3-x64.dll in the $<TARGET_FILE_DIR:tgt> directory:

image

Versions and Environments

  • OS version: Windows 11
  • CMake version: 3.26.3
  • OpenSSL version: 3.0.8
1 Like

cc: @brad.king @craig.scott

The subsequent problem I encountered is that:

I link my executable with the libevent::openssl module of libevent library dynamically. And its runtime dependency event_openssld.dll is indeed copied successfully.

However, event_openssld.dll depends on OpenSSL’s runtime dependencies, libcrypto-3-x64.dll and libssl-3-x64.dll. Therefore, the error messages that the program cannot find those OpenSSL’s runtime dependencies appear.

image

FindOpenSSL’s imported targets, like those of all find modules, are meant for use during the build. When finding shared libraries on Windows, only the .lib import library part is needed for linking. We don’t currently try to find the .dll part at all, let alone populate their location in imported targets. The documentation of $<TARGET_RUNTIME_DLLS> specifically mentions this.

There are some open issues about adding .dll information to find modules and tracking runtime dependencies more explicitly.

@brad.king

So except for “adding bin path to PATH env” and “copying DLLs manually to runtime output directory”, what is the alternative/recommanded way to deal with the situation using dynamic linkage libraries of OpenSSL?

1 Like