c++cmakeopenssllinkermsvc12

Cannot link libcrypto statically w/ cmake


I am building an application that has OpenSSL's libcrypto as a dependency. Up until now i've been linking against it dynamically, but wanted to switch to static linkage.

Searching online, i found that you need to set the flag OPENSSL_USE_STATIC_LIBS to TRUE, reset the build cache, and it should find and link to the static version of OpenSSL (if found). What i see is that CMake does indeed find libcrypto.lib, but the executable still links against the DLL.

Here is the CMake log:

-- The C compiler identification is MSVC 19.38.33133.0
-- The CXX compiler identification is MSVC 19.38.33133.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.38.33130/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.38.33130/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - not found
-- Found Threads: TRUE 
-- Found OpenSSL: C:/Program Files/OpenSSL/lib/libcrypto.lib (found version "3.0.10")  # <== correctly found libcrypto.lib
-- Configuring done (5.3s)
-- Generating done (0.0s)

and the CMakeLists.txt

cmake_minimum_required(VERSION 3.23)
project(common)

set(CMAKE_CXX_STANDARD 20)

set(OPENSSL_USE_STATIC_LIBS TRUE)    # <== set correctly before find_package
find_package(OpenSSL REQUIRED)

add_library(common STATIC
        common.cpp)
target_include_directories(common PUBLIC include)
target_link_libraries(common OpenSSL::Crypto)

I don't see what i'm doing wrong, i checked some posts on here and the answers seem to be doing exactly what i wrote in the CMakeLists (i saw Linking statically OpenSSL crypto library in CMake and Static linking of OpenSSL Crypto in CMake).

Environment


Solution

  • The problem appears that your libcrypto.lib library is not actually a static library but instead it's an import library.

    In the msdn documentation an import library is described as the following:

    An import library (.lib) file contains information that the linker needs in order to resolve external references to exported DLL functions, so that the system can locate the specified DLL and exported DLL functions at run-time. You can create an import library for your DLL when you build your DLL.

    When you link to an import library your program will require the dependent dll to be loaded when your application loads.

    Additionally as @Alan Birtles commented in the question the CMake finder module for OpenSSL will find the import library if the static library is not available:
    https://github.com/Kitware/CMake/blob/041a482079baf690f1bf8e9cdc8a7a1922016267/Modules/FindOpenSSL.cmake#L360