Я создаю приложение, в котором OpenSSL libcrypto
является зависимостью. До сих пор я связывался с ним динамически, но хотел переключиться на статическую связь.
Выполнив поиск в Интернете, я обнаружил, что вам нужно установить флаг OPENSSL_USE_STATIC_LIBS
на TRUE
, сбросить кеш сборки, и он должен найти статическую версию OpenSSL и связать ее с ней (если она найдена). Я вижу, что CMake действительно находит libcrypto.lib
, но исполняемый файл все еще связывается с DLL.
Вот журнал CMake:
-- 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)
и 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)
Я не понимаю, что я делаю неправильно, я проверил несколько сообщений здесь, и ответы, кажется, делают именно то, что я написал в CMakeLists
(я видел Статическое связывание криптобиблиотеки OpenSSL в CMake и Статическое связывание OpenSSL Crypto в CMake).
cmake
: cmake версии 3.28.1 (CMake; пакет IDE JetBrains; сборка 16);cl.exe
: Microsoft (R) C/C++ оптимизирующий компилятор версии 19.38.33133 для x86;LINK.exe
: Microsoft (R) инкрементный компоновщик версии 14.38.33133.0;ninja
: 1.12.0;исполняемый файл по-прежнему связан с DLL. msvc не связывается с DLL для собственного кода, он использует библиотеки импорта, которые имеют расширение .lib, но не содержат реализации и требуют DLL во время выполнения.
где вы взяли двоичные файлы openssl?
см. github.com/Kitware/CMake/blob/… для получения подробной информации о том, как cmake выполняет поиск. Если он не находит статические библиотеки, вместо этого он просто использует общие.
@drescherjm возможно ты прав, lib /list libcrypto.lib
только показывает libcrypto-3-x64.dll
. можете ли вы опубликовать ответ, чтобы я мог его принять?
Проблема заключается в том, что ваша библиотека libcrypto.lib
на самом деле не является статической библиотекой, а является библиотекой импорта.
В документации msdn библиотека импорта описывается следующим образом:
Файл библиотеки импорта (.lib) содержит информацию, которую компоновщик необходимо для разрешения внешних ссылок на экспортированную DLL функции, чтобы система могла найти указанную DLL и экспортированные функции DLL во время выполнения. Вы можете создать библиотеку импорта для вашей DLL, когда вы создаете свою DLL.
Когда вы ссылаетесь на библиотеку импорта, ваша программа потребует загрузки зависимой dll при загрузке вашего приложения.
Кроме того, как прокомментировал @Alan Birtles в вопросе, модуль поиска CMake для OpenSSL найдет библиотеку импорта, если статическая библиотека недоступна:
https://github.com/Kitware/CMake/blob/041a482079baf690f1bf8e9cdc8a7a1922016267/Modules/FindOpenSSL.cmake#L360
Вы уверены, что
libcrypto.lib
— статическая библиотека? Помните, что библиотеки импорта также имеют расширение .lib и во время выполнения им требуется dll.