Есть проект, который собирается под Windows и под Linux. Для управления зависимостями используется vcpkg (вместе с манифестами, т.е. с файлами vcpkg-configuration.json и vcpkg.json, хотя манифесты тут вряд ли виноваты).
В зависимостях есть OpenSSL. Подключение OpenSSL в CMakeLists.txt проекта выглядит стандартным образом:
find_package(OpenSSL CONFIG REQUIRED) ... target_link_libraries(some_executable_file OpenSSL::SSL OpenSSL::Crypto) |
Так вот под Windows все это работает как часы, тогда как под Linux-ом случился нежданчик: внезапно™ выяснилось, что нет таких CMake-овских таргетов, как OpenSSL::SSL и OpenSSL::Crypto.
Вот нет и все, хотя find_package успешно отрабатывает.
Блуждания по потрохам кучи CMake-овских файлов, установленных vcpkg, привело вот к такому фрагменту в файле OpenSSLConfig.cmake, который лежит в vcpkg_installed/x64-linux/share/openssl (извиняюсь за его объем, но здесь все самое важное):
if(NOT Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG) # Prevent loop set(Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG "prevent-loop") # Chainload vcpkg's module-based multi-config target setup find_package(OpenSSL MODULE) set(Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG 0) else() # Use official single-config target setup # Set up the imported targets if(_ossl_use_static_libs) add_library(OpenSSL::Crypto STATIC IMPORTED) add_library(OpenSSL::SSL STATIC IMPORTED) set(OPENSSL_LIBCRYPTO_STATIC "${OPENSSL_LIBRARY_DIR}/libcrypto.a") set(OPENSSL_LIBCRYPTO_DEPENDENCIES -ldl -pthread) set_target_properties(OpenSSL::Crypto PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" IMPORTED_LOCATION ${OPENSSL_LIBCRYPTO_STATIC}) set_property(TARGET OpenSSL::Crypto PROPERTY INTERFACE_LINK_LIBRARIES ${OPENSSL_LIBCRYPTO_DEPENDENCIES}) set(OPENSSL_LIBSSL_STATIC "${OPENSSL_LIBRARY_DIR}/libssl.a") set(OPENSSL_LIBSSL_DEPENDENCIES OpenSSL::Crypto) set_target_properties(OpenSSL::SSL PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" IMPORTED_LOCATION ${OPENSSL_LIBSSL_STATIC}) set_property(TARGET OpenSSL::SSL PROPERTY INTERFACE_LINK_LIBRARIES ${OPENSSL_LIBSSL_DEPENDENCIES}) # Directories and names compatible with CMake's FindOpenSSL.cmake set(OPENSSL_CRYPTO_LIBRARY ${OPENSSL_LIBCRYPTO_STATIC}) set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY} ${OPENSSL_LIBCRYPTO_DEPENDENCIES}) set(OPENSSL_SSL_LIBRARY ${OPENSSL_LIBSSL_STATIC}) set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_LIBSSL_DEPENDENCIES}) set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_LIBSSL_DEPENDENCIES} ${OPENSSL_LIBCRYPTO_DEPENDENCIES}) else() # Shared libraries are UNSUPPORTED in this configuration endif() |
Итак, суть в том, что если переменная Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG не установлена (а она не установлена), то делается еще один find_package(OpenSSL), после которого никаких таргетов OpenSSL::SSL/Crypto не определяется. Но вот если Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG установлена, то тогда эти таргеты для случая статической библиотеки должным образом определяются.
Поэтому-то таргетов OpenSSL::SSL/Crypto нет, и попытка их использования ведет к ошибкам в проектном CMakeLists.txt.
Почему таргеты OpenSSL::SSL/Crypto есть при работе с OpenSSL в Windows -- я ХЗ.
Тут, вероятно, какая-то магия vcpkg, поскольку проблемные строчки добавляются в специальном patch-файле в порте OpenSSL для vcpkg (цинк).
Причем не только мы наступили на эти грабли. Есть до сих пор открытый issue на github-е с описанием сути проблемы. К сожалению, я его нашел уже после того, как сам дорылся до причины.
В качестве обходного маневра в проектный CMakeLists.txt для Linux-а была добавлена строчка:
set(Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG ON) |
перед вызовом find_package(OpenSSL).
Комментариев нет:
Отправить комментарий