Проблема при линковке winsock2 через CMake в MinGW - Undefined reference
Хочу реализовать небольшой utility-executable для работы с HTTP/HTTPS.
Использую CLion 2020.1, Windows 10, MinGW x64, Single-header HTTP lib: https://github.com/yhirose/cpp-httplib
Библиотеке для корректной работы требуются libcrypto.a и libssl.a из OpenSSL 1.1.1 (https://github.com/openssl/openssl), которые я собрал с помощью MSYS2 (MinGW x64) и добавил в директорию с исходным кодом.
Структура исходного кода:
/Main.cpp
/CMakeLists.txt
/httplib.h
/libraries/openssl/bin/..
/libraries/openssl/include/..
Note: Приведенный ниже C++ код взят из примеров cpp-httplib.
Main.cpp
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include <httplib.h>
int main() {
downloadImage();
}
void downloadImage() {
httplib::SSLClient cli("media.wired.com");
cli.enable_server_certificate_verification(true);
// prints: 0 / 000 bytes => 50% complete
auto res = cli.Get("/photos/59326d5344db296121d6aee9/master/pass/8552.gif", [](uint64_t len, uint64_t total) {
printf("%lld / %lld bytes => %d%% complete\n",
len, total,
(int)(len * 100 / total));
return true; // return 'false' if you want to cancel the request.
}
);
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(Application)
set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES Main.cpp httplib.h)
add_executable(Application ${SOURCE_FILES})
include_directories(${CMAKE_SOURCE_DIR}/libraries/openssl/include)
target_link_libraries(Application PRIVATE ${CMAKE_SOURCE_DIR}/libraries/openssl/lib/libssl.a ${CMAKE_SOURCE_DIR}/libraries/openssl/lib/libcrypto.a ws2_32)
При попытке собрать и запустить проект в CLion возникает ряд ошибок:
====================[ Build | Application | Debug ]============
"C:\Program Files\JetBrains\CLion 2020.1\bin\cmake\win\bin\cmake.exe" --build D:\Git\Application\cmake-build-debug --target Application -- -j 12
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Git/Application/cmake-build-debug
[ 33%] Linking CXX executable Application.exe
CMakeFiles\Application.dir/objects.a(Main.cpp.obj): In function `httplib::detail::load_system_certs_on_windows(x509_store_st*)':
D:/Git/Application/httplib.h:4082: undefined reference to `__imp_CertOpenSystemStoreW'
D:/Git/Application/httplib.h:4087: undefined reference to `__imp_CertEnumCertificatesInStore'
D:/Git/Application/httplib.h:4099: undefined reference to `__imp_CertFreeCertificateContext'
D:/Git/Application/httplib.h:4100: undefined reference to `__imp_CertCloseStore'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0xe0): undefined reference to `__imp_CertFreeCertificateContext'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x160): undefined reference to `__imp_CertFreeCertificateContext'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x56d): undefined reference to `__imp_CertGetCertificateContextProperty'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0xadc): undefined reference to `__imp_CertGetCertificateContextProperty'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0xc2e): undefined reference to `__imp_CertEnumCertificatesInStore'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0xce1): undefined reference to `__imp_CertFindCertificateInStore'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x2ca5): undefined reference to `__imp_CertOpenStore'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x2cd8): undefined reference to `__imp_CertEnumCertificatesInStore'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x2de4): undefined reference to `__imp_CertDuplicateCertificateContext'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x2e4e): undefined reference to `__imp_CertCloseStore'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x2e89): undefined reference to `__imp_CertFreeCertificateContext'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x3590): undefined reference to `__imp_CertOpenStore'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x35d5): undefined reference to `__imp_CertFreeCertificateContext'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x35e0): undefined reference to `__imp_CertCloseStore'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x3603): undefined reference to `__imp_CertEnumCertificatesInStore'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x3d47): undefined reference to `__imp_CertOpenStore'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x3db5): undefined reference to `__imp_CertFreeCertificateContext'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x3dc0): undefined reference to `__imp_CertCloseStore'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x3ee9): undefined reference to `__imp_CertFreeCertificateContext'
../libraries/openssl/lib/libcrypto.a(e_capi.o):e_capi.c:(.text+0x3f80): undefined reference to `__imp_CertFreeCertificateContext'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [CMakeFiles\Application.dir\build.make:104: Application.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:75: CMakeFiles/Application.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:82: CMakeFiles/Application.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:117: Application] Error 2
Судя по тому, что я нашел на StackOverflow возможно проблема как-то связана с winsock2 и MinGW, но вроде я явно указал в CMakeLists что её нужно добавить, и CMake не ругается, что она не найдена, подскажите в чем может быть дело?
Ответы (1 шт):
Исправленный вариант target_link_libraries() из CMakeLists.txt:
target_link_libraries(Application PRIVATE ${CMAKE_SOURCE_DIR}/libraries/openssl/lib/libssl.a ${CMAKE_SOURCE_DIR}/libraries/openssl/lib/libcrypto.a crypt32 ws2_32)