1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2026-05-20 12:22:13 +00:00

CMake: improve OpenSSL/GnuTLS detection

This commit is contained in:
Carles Fernandez
2026-05-08 20:51:35 +02:00
parent b37334d964
commit 4fa64ce482
+380 -113
View File
@@ -1,7 +1,7 @@
# GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
# This file is part of GNSS-SDR.
#
# SPDX-FileCopyrightText: 2024-2025 C. Fernandez-Prades cfernandez(at)cttc.es
# SPDX-FileCopyrightText: 2024-2026 C. Fernandez-Prades cfernandez(at)cttc.es
# SPDX-License-Identifier: BSD-3-Clause
if(NOT COMMAND feature_summary)
@@ -12,177 +12,444 @@ if(NOT DEFINED GNSSSDR_LIB_PATHS)
include(GnsssdrFindPaths)
endif()
set(GNSSSDR_OPENSSL_FOUND FALSE)
set(GNSSSDR_OPENSSL_VERSION "")
set(GNSSSDR_OPENSSL_VERSION_NUMBER "")
set(GNSSSDR_GNUTLS_FOUND FALSE)
set(GNSSSDR_GNUTLS_VERSION "")
set(GNSSSDR_GNUTLS_INCLUDE_DIR "")
################################################################################
# OpenSSL https://www.openssl.org/
################################################################################
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(OPENSSL_ROOT_DIR /usr/local/opt/openssl) # Trick for Homebrew
if("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
if((NOT DEFINED OPENSSL_ROOT_DIR) OR ("${OPENSSL_ROOT_DIR}" STREQUAL ""))
foreach(_gnsssdr_openssl_root_candidate
/opt/homebrew/opt/openssl@3
/usr/local/opt/openssl@3
/opt/homebrew/opt/openssl
/usr/local/opt/openssl
/opt/local
)
if(EXISTS "${_gnsssdr_openssl_root_candidate}/include/openssl/ssl.h")
set(OPENSSL_ROOT_DIR "${_gnsssdr_openssl_root_candidate}")
break()
endif()
endforeach()
unset(_gnsssdr_openssl_root_candidate)
endif()
endif()
unset(OPENSSL_FOUND CACHE)
unset(GnuTLS_FOUND CACHE)
unset(GMP_FOUND CACHE)
if(NOT ENABLE_GNUTLS)
find_package(OpenSSL)
if(CMAKE_VERSION VERSION_LESS "3.12")
find_package(OpenSSL)
else()
find_package(OpenSSL COMPONENTS SSL)
endif()
if(OpenSSL_FOUND OR OPENSSL_FOUND)
set(GNSSSDR_OPENSSL_FOUND TRUE)
endif()
# CMake < 3.12 did not support OpenSSL components. Check that libssl was
# actually found, because gnss-sdr needs both SSL/TLS and crypto support.
if(GNSSSDR_OPENSSL_FOUND AND CMAKE_VERSION VERSION_LESS "3.12")
if((NOT TARGET OpenSSL::SSL) AND
(NOT OPENSSL_SSL_LIBRARY) AND
(NOT OPENSSL_SSL_LIBRARIES))
set(GNSSSDR_OPENSSL_FOUND FALSE)
endif()
endif()
if(OpenSSL_VERSION)
set(GNSSSDR_OPENSSL_VERSION "${OpenSSL_VERSION}")
elseif(OPENSSL_VERSION)
set(GNSSSDR_OPENSSL_VERSION "${OPENSSL_VERSION}")
endif()
if(GNSSSDR_OPENSSL_VERSION)
string(REGEX MATCH "^[0-9]+(\\.[0-9]+)*"
GNSSSDR_OPENSSL_VERSION_NUMBER
"${GNSSSDR_OPENSSL_VERSION}"
)
endif()
if(GNSSSDR_OPENSSL_FOUND)
if(GNSSSDR_OPENSSL_VERSION)
set_package_properties(OpenSSL
PROPERTIES
URL "https://www.openssl.org"
DESCRIPTION "Cryptography and SSL/TLS Toolkit (found: v${GNSSSDR_OPENSSL_VERSION})"
PURPOSE "Used for the OSNMA and SUPL protocol implementations."
TYPE REQUIRED
)
else()
set_package_properties(OpenSSL
PROPERTIES
URL "https://www.openssl.org"
DESCRIPTION "Cryptography and SSL/TLS Toolkit"
PURPOSE "Used for the OSNMA and SUPL protocol implementations."
TYPE REQUIRED
)
endif()
else()
set_package_properties(OpenSSL
PROPERTIES
URL "https://www.openssl.org"
DESCRIPTION "OpenSSL has not been found, but GnuTLS with OpenSSL compatibility can replace it."
PURPOSE "Used for the OSNMA and SUPL protocol implementations."
TYPE RECOMMENDED
)
endif()
endif()
set_package_properties(OpenSSL
PROPERTIES
URL "https://www.openssl.org"
PURPOSE "Used for the OSNMA and SUPL protocol implementations."
TYPE REQUIRED
)
if(OPENSSL_FOUND)
set_package_properties(OpenSSL
PROPERTIES
DESCRIPTION "Cryptography and SSL/TLS Toolkit (found: v${OPENSSL_VERSION})"
)
else()
set_package_properties(OpenSSL
PROPERTIES
DESCRIPTION "OpenSSL has not been found, but GnuTLS with openssl compatibility can replace it"
)
################################################################################
# GnuTLS - https://www.gnutls.org/
################################################################################
################################################################################
# GnuTLS https://www.gnutls.org/
################################################################################
if(NOT GNSSSDR_OPENSSL_FOUND)
find_package(GnuTLS)
set_package_properties(GnuTLS PROPERTIES
URL "https://www.gnutls.org/"
PURPOSE "Used for the OSNMA and SUPL protocol implementations."
TYPE REQUIRED
)
if(GnuTLS_FOUND AND GNUTLS_VERSION_STRING)
set_package_properties(GnuTLS PROPERTIES
DESCRIPTION "Transport Layer Security Library (found: v${GNUTLS_VERSION_STRING})"
if(GnuTLS_FOUND OR GNUTLS_FOUND)
set(GNSSSDR_GNUTLS_FOUND TRUE)
endif()
if(GnuTLS_VERSION)
set(GNSSSDR_GNUTLS_VERSION "${GnuTLS_VERSION}")
elseif(GNUTLS_VERSION)
set(GNSSSDR_GNUTLS_VERSION "${GNUTLS_VERSION}")
elseif(GNUTLS_VERSION_STRING)
set(GNSSSDR_GNUTLS_VERSION "${GNUTLS_VERSION_STRING}")
endif()
if(GNSSSDR_GNUTLS_VERSION)
set_package_properties(GnuTLS
PROPERTIES
URL "https://www.gnutls.org/"
DESCRIPTION "Transport Layer Security Library (found: v${GNSSSDR_GNUTLS_VERSION})"
PURPOSE "Used for the OSNMA and SUPL protocol implementations."
TYPE REQUIRED
)
else()
set_package_properties(GnuTLS PROPERTIES
DESCRIPTION "Transport Layer Security Library"
set_package_properties(GnuTLS
PROPERTIES
URL "https://www.gnutls.org/"
DESCRIPTION "Transport Layer Security Library"
PURPOSE "Used for the OSNMA and SUPL protocol implementations."
TYPE REQUIRED
)
endif()
set(_gnsssdr_gnutls_library_paths ${GNSSSDR_LIB_PATHS})
if(GNUTLS_ROOT_DIR)
list(APPEND _gnsssdr_gnutls_library_paths
"${GNUTLS_ROOT_DIR}/lib"
"${GNUTLS_ROOT_DIR}/lib64"
)
endif()
find_library(GNUTLS_OPENSSL_LIBRARY
NAMES gnutls-openssl libgnutls-openssl.so.27
PATHS ${GNSSSDR_LIB_PATHS}
PATHS ${_gnsssdr_gnutls_library_paths}
)
unset(_gnsssdr_gnutls_library_paths)
find_path(GNUTLS_INCLUDE_DIR NAMES gnutls/gnutls.h
PATHS
${GNSSSDR_INCLUDE_PATHS}
${GNUTLS_ROOT_DIR}/include/
set(_gnsssdr_gnutls_include_paths ${GNSSSDR_INCLUDE_PATHS})
if(GNUTLS_ROOT_DIR)
list(APPEND _gnsssdr_gnutls_include_paths
"${GNUTLS_ROOT_DIR}/include"
)
endif()
find_path(GNUTLS_INCLUDE_DIR
NAMES gnutls/gnutls.h
PATHS ${_gnsssdr_gnutls_include_paths}
)
unset(_gnsssdr_gnutls_include_paths)
if(NOT GNUTLS_OPENSSL_LIBRARY)
message(" The GnuTLS library with openssl compatibility enabled has not been found.")
message(" You can try to install the required libraries by typing:")
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU")
if("${LINUX_DISTRIBUTION}" MATCHES "Fedora" OR "${LINUX_DISTRIBUTION}" MATCHES "Red Hat")
message(" sudo yum install openssl-devel")
if(GNUTLS_INCLUDE_DIR)
set(GNSSSDR_GNUTLS_INCLUDE_DIR "${GNUTLS_INCLUDE_DIR}")
elseif(GNUTLS_INCLUDE_DIRS)
set(_gnsssdr_gnutls_include_dirs ${GNUTLS_INCLUDE_DIRS})
list(GET _gnsssdr_gnutls_include_dirs 0 GNSSSDR_GNUTLS_INCLUDE_DIR)
unset(_gnsssdr_gnutls_include_dirs)
endif()
if((NOT GNSSSDR_GNUTLS_FOUND) OR
(NOT GNUTLS_OPENSSL_LIBRARY) OR
(NOT GNSSSDR_GNUTLS_INCLUDE_DIR))
message(STATUS "The GnuTLS library with OpenSSL compatibility has not been found.")
message(STATUS "You can try to install the required libraries by typing:")
if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux|kFreeBSD|GNU")
if("${LINUX_DISTRIBUTION}" MATCHES "Fedora" OR
"${LINUX_DISTRIBUTION}" MATCHES "Red Hat")
message(STATUS " sudo yum install openssl-devel gnutls-devel")
else()
message(" sudo apt install libgnutls28-dev")
message(STATUS " sudo apt install libssl-dev libgnutls28-dev")
endif()
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
message(" 'sudo port install openssl3', if you are using Macports, or")
message(" 'brew install openssl', if you are using Homebrew.")
if("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
message(STATUS " sudo port install openssl3, if you are using MacPorts, or")
message(STATUS " brew install openssl@3, if you are using Homebrew.")
endif()
message(FATAL_ERROR "OpenSSL or the GnuTLS libraries with openssl compatibility are required to build gnss-sdr")
message(FATAL_ERROR
"OpenSSL or GnuTLS with OpenSSL compatibility is required "
"to build gnss-sdr"
)
endif()
# Test GnuTLS capabilities
file(READ "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h" gnutls_gnutls_file_contents)
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_SIGN_ECDSA_SHA256")
set(GNUTLS_SIGN_ECDSA_SHA256 TRUE)
set(GNUTLS_SIGN_ECDSA_SHA256 FALSE)
set(GNUTLS_SIGN_ECDSA_SHA512 FALSE)
set(GNUTLS_DIG_SHA3_256 FALSE)
set(GNUTLS_HMAC_INIT_WITH_DIGEST FALSE)
set(GNUTLS_MAC_AES_CMAC_128 FALSE)
set(GNUTLS_PUBKEY_EXPORT2 FALSE)
set(_gnsssdr_gnutls_header
"${GNSSSDR_GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h"
)
set(_gnsssdr_gnutls_abstract_header
"${GNSSSDR_GNUTLS_INCLUDE_DIR}/gnutls/abstract.h"
)
if(EXISTS "${_gnsssdr_gnutls_header}")
file(READ "${_gnsssdr_gnutls_header}" gnutls_gnutls_file_contents)
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_SIGN_ECDSA_SHA256")
set(GNUTLS_SIGN_ECDSA_SHA256 TRUE)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_SIGN_ECDSA_SHA512")
set(GNUTLS_SIGN_ECDSA_SHA512 TRUE)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_DIG_SHA3_256")
set(GNUTLS_DIG_SHA3_256 TRUE)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "#define GNUTLS_VERSION_MAJOR 2")
set(GNUTLS_HMAC_INIT_WITH_DIGEST TRUE)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_MAC_AES_CMAC_128")
set(GNUTLS_MAC_AES_CMAC_128 TRUE)
endif()
else()
message(FATAL_ERROR
"The GnuTLS header ${_gnsssdr_gnutls_header} has not been found"
)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_SIGN_ECDSA_SHA512")
set(GNUTLS_SIGN_ECDSA_SHA512 TRUE)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_DIG_SHA3_256")
set(GNUTLS_DIG_SHA3_256 TRUE)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "#define GNUTLS_VERSION_MAJOR 2")
set(GNUTLS_HMAC_INIT_WITH_DIGEST TRUE)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_MAC_AES_CMAC_128")
set(GNUTLS_MAC_AES_CMAC_128 TRUE)
endif()
file(READ "${GNUTLS_INCLUDE_DIR}/gnutls/abstract.h" gnutls_abstract_file_contents)
if("${gnutls_abstract_file_contents}" MATCHES "gnutls_pubkey_export2")
set(GNUTLS_PUBKEY_EXPORT2 TRUE)
if(EXISTS "${_gnsssdr_gnutls_abstract_header}")
file(READ
"${_gnsssdr_gnutls_abstract_header}"
gnutls_abstract_file_contents
)
if("${gnutls_abstract_file_contents}" MATCHES "gnutls_pubkey_export2")
set(GNUTLS_PUBKEY_EXPORT2 TRUE)
endif()
endif()
unset(_gnsssdr_gnutls_header)
unset(_gnsssdr_gnutls_abstract_header)
find_package(GMP)
set_package_properties(GMP PROPERTIES
PURPOSE "Required to decompress cryptographic keys."
TYPE REQUIRED
set_package_properties(GMP
PROPERTIES
URL "https://gmplib.org/"
PURPOSE "Required to decompress cryptographic keys."
TYPE REQUIRED
)
if(NOT GMP_FOUND)
message(FATAL_ERROR "GMP is required by gnss-sdr if linking against GnuTLS")
message(FATAL_ERROR
"GMP is required by gnss-sdr when linking against GnuTLS"
)
endif()
endif()
################################################################################
function(link_to_crypto_dependencies target)
if(OPENSSL_FOUND)
if("${target}" STREQUAL "")
message(FATAL_ERROR "link_to_crypto_dependencies called without a target")
endif()
if(NOT TARGET ${target})
message(FATAL_ERROR
"link_to_crypto_dependencies called for unknown target: ${target}"
)
endif()
if(GNSSSDR_OPENSSL_FOUND)
if(TARGET OpenSSL::SSL)
target_link_libraries(${target}
PUBLIC
OpenSSL::SSL
)
if(TARGET OpenSSL::Crypto)
if(MSVC AND TARGET OpenSSL::applink)
target_link_libraries(${target}
PUBLIC
OpenSSL::Crypto
PRIVATE
OpenSSL::applink
)
endif()
else()
target_link_libraries(${target}
PUBLIC
${OPENSSL_LIBRARIES}
"${OPENSSL_CRYPTO_LIBRARIES}"
)
target_include_directories(${target}
PUBLIC
${OPENSSL_INCLUDE_DIR}
)
set(_gnsssdr_openssl_libraries ${OPENSSL_LIBRARIES})
if(NOT _gnsssdr_openssl_libraries)
list(APPEND _gnsssdr_openssl_libraries
${OPENSSL_SSL_LIBRARIES}
${OPENSSL_CRYPTO_LIBRARIES}
${OPENSSL_SSL_LIBRARY}
${OPENSSL_CRYPTO_LIBRARY}
)
endif()
if(_gnsssdr_openssl_libraries)
list(REMOVE_DUPLICATES _gnsssdr_openssl_libraries)
target_link_libraries(${target}
PUBLIC
${_gnsssdr_openssl_libraries}
)
endif()
if(OPENSSL_INCLUDE_DIR)
target_include_directories(${target}
PUBLIC
${OPENSSL_INCLUDE_DIR}
)
elseif(OPENSSL_INCLUDE_DIRS)
target_include_directories(${target}
PUBLIC
${OPENSSL_INCLUDE_DIRS}
)
endif()
unset(_gnsssdr_openssl_libraries)
endif()
if(OPENSSL_VERSION)
if(OPENSSL_VERSION VERSION_GREATER "3.0.0")
target_compile_definitions(${target} PUBLIC -DUSE_OPENSSL_3=1)
else()
if(NOT OPENSSL_VERSION VERSION_LESS "1.1.1")
target_compile_definitions(${target} PUBLIC -DUSE_OPENSSL_111=1)
endif()
if(GNSSSDR_OPENSSL_VERSION_NUMBER)
if(NOT "${GNSSSDR_OPENSSL_VERSION_NUMBER}" VERSION_LESS "3.0.0")
target_compile_definitions(${target}
PUBLIC
USE_OPENSSL_3=1
)
elseif(NOT "${GNSSSDR_OPENSSL_VERSION_NUMBER}" VERSION_LESS "1.1.1")
target_compile_definitions(${target}
PUBLIC
USE_OPENSSL_111=1
)
endif()
endif()
else() # GnuTLS
target_link_libraries(${target}
else()
if(TARGET GnuTLS::GnuTLS)
target_link_libraries(${target}
PUBLIC
GnuTLS::GnuTLS
${GNUTLS_OPENSSL_LIBRARY}
)
else()
target_link_libraries(${target}
PUBLIC
${GNUTLS_LIBRARIES}
${GNUTLS_OPENSSL_LIBRARY}
)
if(GNUTLS_INCLUDE_DIRS)
target_include_directories(${target}
PUBLIC
${GNUTLS_INCLUDE_DIRS}
)
elseif(GNSSSDR_GNUTLS_INCLUDE_DIR)
target_include_directories(${target}
PUBLIC
${GNSSSDR_GNUTLS_INCLUDE_DIR}
)
endif()
endif()
if(COMMAND target_compile_options AND GNUTLS_DEFINITIONS)
target_compile_options(${target}
PUBLIC
${GNUTLS_DEFINITIONS}
)
endif()
if(TARGET Gmp::gmp)
target_link_libraries(${target}
PRIVATE
Gmp::gmp
)
else()
if(GMP_LIBRARIES)
target_link_libraries(${target}
PRIVATE
${GMP_LIBRARIES}
)
endif()
if(GMP_INCLUDE_DIR)
target_include_directories(${target}
PRIVATE
${GMP_INCLUDE_DIR}
)
elseif(GMP_INCLUDE_DIRS)
target_include_directories(${target}
PRIVATE
${GMP_INCLUDE_DIRS}
)
endif()
endif()
target_compile_definitions(${target}
PUBLIC
${GNUTLS_LIBRARIES}
${GNUTLS_OPENSSL_LIBRARY}
PRIVATE
Gmp::gmp
USE_GNUTLS_FALLBACK=1
)
target_include_directories(${target}
PUBLIC
${GNUTLS_INCLUDE_DIR}
)
target_compile_definitions(${target} PUBLIC -DUSE_GNUTLS_FALLBACK=1)
if(GNUTLS_SIGN_ECDSA_SHA256)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_SIGN_ECDSA_SHA256=1)
target_compile_definitions(${target}
PRIVATE
HAVE_GNUTLS_SIGN_ECDSA_SHA256=1
)
endif()
if(GNUTLS_SIGN_ECDSA_SHA512)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_SIGN_ECDSA_SHA512=1)
target_compile_definitions(${target}
PRIVATE
HAVE_GNUTLS_SIGN_ECDSA_SHA512=1
)
endif()
if(GNUTLS_DIG_SHA3_256)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_DIG_SHA3_256=1)
target_compile_definitions(${target}
PRIVATE
HAVE_GNUTLS_DIG_SHA3_256=1
)
endif()
if(GNUTLS_PUBKEY_EXPORT2)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_PUBKEY_EXPORT2=1)
target_compile_definitions(${target}
PRIVATE
HAVE_GNUTLS_PUBKEY_EXPORT2=1
)
endif()
if(GNUTLS_HMAC_INIT_WITH_DIGEST)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_HMAC_INIT_WITH_DIGEST=1)
target_compile_definitions(${target}
PRIVATE
HAVE_GNUTLS_HMAC_INIT_WITH_DIGEST=1
)
endif()
if(GNUTLS_MAC_AES_CMAC_128)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_MAC_AES_CMAC_128=1)
target_compile_definitions(${target}
PRIVATE
HAVE_GNUTLS_MAC_AES_CMAC_128=1
)
endif()
endif()
endfunction()
endfunction()