如何使用 CMake FetchContent 到 link OpenSSL?

How to use CMake FetchContent to link OpenSSL?

如果 find_package 找不到,我不太明白如何通过 FetchContent 集成库。

目前,我有以下代码:

# OpenSSL dependency
option(USE_SYSTEM_OPENSSL "Use preinstalled OpenSSL" ON)

# configure OpenSSL
if(USE_SYSTEM_OPENSSL)
    find_package(OpenSSL COMPONENTS Crypto SSL)
endif()
if(NOT USE_SYSTEM_OPENSSL OR NOT OPENSSL_FOUND)
    # get dependencies from net
    include(FetchContent)

    message(STATUS "Not using system OpenSSL, using built-in OpenSSL project instead.")
    FetchContent_Declare(
        OpenSSL
            GIT_REPOSITORY https://github.com/openssl/openssl
            GIT_TAG        master
            USES_TERMINAL_DOWNLOAD TRUE)
    FetchContent_MakeAvailable(OpenSSL)

    # (1) ...

endif()

#(2)
target_link_libraries(target OpenSSL::SSL OpenSSL::Crypto)

我应该在 (1) 处写些什么才能使 (2) 起作用?

不能使用FetchContent_Declare,必须使用ExternalProject_Add:

set(OPENSSL_SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/openssl-src) # default path by CMake
set(OPENSSL_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/openssl)
set(OPENSSL_INCLUDE_DIR ${OPENSSL_INSTALL_DIR}/include)
set(OPENSSL_CONFIGURE_COMMAND ${OPENSSL_SOURCE_DIR}/config)
ExternalProject_Add(
  OpenSSL
  SOURCE_DIR ${OPENSSL_SOURCE_DIR}
  GIT_REPOSITORY https://github.com/openssl/openssl.git
  GIT_TAG OpenSSL_1_1_1n
  USES_TERMINAL_DOWNLOAD TRUE
  CONFIGURE_COMMAND
    ${OPENSSL_CONFIGURE_COMMAND}
    --prefix=${OPENSSL_INSTALL_DIR}
    --openssldir=${OPENSSL_INSTALL_DIR}
  BUILD_COMMAND make
  TEST_COMMAND ""
  INSTALL_COMMAND make install
  INSTALL_DIR ${OPENSSL_INSTALL_DIR}
)

完成后,您还不能将其包含或 link 与其他目标一起使用。为此,您仍然需要声明库,就像使用 find_package 找到它一样,即 就像使用 FindOpenSSL.cmake 一样:

# We cannot use find_library because ExternalProject_Add() is performed at build time.
# And to please the property INTERFACE_INCLUDE_DIRECTORIES,
# we make the include directory in advance.
file(MAKE_DIRECTORY ${OPENSSL_INCLUDE_DIR})

add_library(OpenSSL::SSL STATIC IMPORTED GLOBAL)
set_property(TARGET OpenSSL::SSL PROPERTY IMPORTED_LOCATION ${OPENSSL_INSTALL_DIR}/lib/libssl.${OPENSSL_LIBRARY_SUFFIX})
set_property(TARGET OpenSSL::SSL PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${OPENSSL_INCLUDE_DIR})
add_dependencies(OpenSSL::SSL OpenSSL)

add_library(OpenSSL::Crypto STATIC IMPORTED GLOBAL)
set_property(TARGET OpenSSL::Crypto PROPERTY IMPORTED_LOCATION ${OPENSSL_INSTALL_DIR}/lib/libcrypto.${OPENSSL_LIBRARY_SUFFIX})
set_property(TARGET OpenSSL::Crypto PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${OPENSSL_INCLUDE_DIR})
add_dependencies(OpenSSL::Crypto OpenSSL)

现在您可以正常包含 OpenSSL 和 link。