diff options
Diffstat (limited to 'cmake/Modules')
-rw-r--r-- | cmake/Modules/AdocMan.cmake | 135 | ||||
-rw-r--r-- | cmake/Modules/FindBotan2.cmake | 131 | ||||
-rw-r--r-- | cmake/Modules/FindGnuPG.cmake | 137 | ||||
-rw-r--r-- | cmake/Modules/FindJSON-C.cmake | 123 | ||||
-rw-r--r-- | cmake/Modules/FindOpenSSLFeatures.cmake | 171 | ||||
-rw-r--r-- | cmake/Modules/FindWindowsSDK.cmake | 662 | ||||
-rw-r--r-- | cmake/Modules/findopensslfeatures.c | 101 |
7 files changed, 1460 insertions, 0 deletions
diff --git a/cmake/Modules/AdocMan.cmake b/cmake/Modules/AdocMan.cmake new file mode 100644 index 0000000..96c5c93 --- /dev/null +++ b/cmake/Modules/AdocMan.cmake @@ -0,0 +1,135 @@ +# Copyright (c) 2021 Ribose Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +#.adoc: +# add_adoc_man +# ----------- +# +# Convert adoc manual page to troff and install it via the custom target. +# +# Parameters +# ^^^^^^^^^^ +# Required parameter is source with markdown file. Must have md extension with man category prepended, i.e. something like ${CMAKE_SOURCE_DIR}/src/utility.1.adoc +# DST - optional parameter, which overrides where generated man will be stored. +# If not specified then will be automatically set to ${CMAKE_BINARY_DIR}/src/utility.1 +# +# Generated man page will be installed via the target, named man_utility +# + +set(ADOCCOMMAND_FOUND 0) +find_program(ADOCCOMMAND_PATH + NAMES asciidoctor + DOC "Path to AsciiDoc processor. Used to generate man pages from AsciiDoc." +) + +if(NOT EXISTS ${ADOCCOMMAND_PATH}) + set(ADOC_MISSING_MSG "AsciiDoc processor not found, man pages will not be generated. Install asciidoctor or use the CMAKE_PROGRAM_PATH variable.") + + string(TOLOWER "${ENABLE_DOC}" ENABLE_DOC) + if (ENABLE_DOC STREQUAL "auto") + message(WARNING ${ADOC_MISSING_MSG}) + elseif(ENABLE_DOC) + message(FATAL_ERROR ${ADOC_MISSING_MSG}) + endif() +else() + set(ADOCCOMMAND_FOUND 1) +endif() + +function(add_adoc_man SRC COMPONENT_VERSION) + if (NOT ${ADOCCOMMAND_FOUND}) + return() + endif() + + cmake_parse_arguments( + ARGS + "" + "DST" + "" + ${ARGN} + ) + + set(ADOC_EXT ".adoc") + get_filename_component(FILE_NAME ${SRC} NAME) + + # The following procedures check against the expected file name + # pattern: "{name}.{man-number}.adoc", and builds to a + # destination file "{name}.{man-number}". + + # Check SRC extension + get_filename_component(END_EXT ${SRC} LAST_EXT) + string(COMPARE EQUAL ${END_EXT} ${ADOC_EXT} _equal) + if (NOT _equal) + message(FATAL_ERROR "SRC must have ${ADOC_EXT} extension.") + endif() + + # Check man number + get_filename_component(EXTS ${SRC} EXT) + string(REGEX MATCH "^\.([1-9])\.+$" _matches ${EXTS}) + set(MAN_NUM ${CMAKE_MATCH_1}) + if (NOT _matches) + message(FATAL_ERROR "Man file with wrong name pattern: ${FILE_NAME} must be in format {name}.[0-9]${ADOC_EXT}.") + endif() + + # Set target name + get_filename_component(TARGET_NAME ${SRC} NAME_WE) + string(PREPEND TARGET_NAME "man_") + + # Build output path if not specified. + if(NOT DST) + get_filename_component(SRC_PREFIX ${SRC} DIRECTORY) + + # Ensure that SRC_PREFIX is within CMAKE_SOURCE_DIR + if(NOT(SRC_PREFIX MATCHES "^${CMAKE_SOURCE_DIR}")) + message(FATAL_ERROR "Cannot build DST path as SRC is outside of the CMake sources dir.") + endif() + STRING(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/" "" SUBDIR_PATH ${SRC}) + + # Strip '.adoc' from the output subpath + get_filename_component(SUBDIR_PATH_NAME_WLE ${SUBDIR_PATH} NAME_WLE) + get_filename_component(SUBDIR_PATH_DIRECTORY ${SUBDIR_PATH} DIRECTORY) + set(DST "${CMAKE_BINARY_DIR}/${SUBDIR_PATH_DIRECTORY}/${SUBDIR_PATH_NAME_WLE}") + endif() + + # Check conformance of destination file name to pattern + get_filename_component(FILE_NAME_WE ${SRC} NAME_WE) + get_filename_component(MAN_FILE_NAME ${DST} NAME) + if(NOT(MAN_FILE_NAME MATCHES "^${FILE_NAME_WE}.${MAN_NUM}$")) + message(FATAL_ERROR "File name of a man page must be in the format {name}.{man-number}${ADOC_EXT}.") + endif() + + add_custom_command( + OUTPUT ${DST} + COMMAND ${ADOCCOMMAND_PATH} -b manpage ${SRC} -o ${DST} -a component-version=${COMPONENT_VERSION} + DEPENDS ${SRC} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Generating man page ${SUBDIR_PATH_DIRECTORY}/${SUBDIR_PATH_NAME_WLE}" + VERBATIM + ) + + add_custom_target("${TARGET_NAME}" ALL DEPENDS ${DST}) + install(FILES ${DST} + DESTINATION "${CMAKE_INSTALL_FULL_MANDIR}/man${MAN_NUM}" + COMPONENT doc + ) +endfunction(add_adoc_man) diff --git a/cmake/Modules/FindBotan2.cmake b/cmake/Modules/FindBotan2.cmake new file mode 100644 index 0000000..2708491 --- /dev/null +++ b/cmake/Modules/FindBotan2.cmake @@ -0,0 +1,131 @@ +# Copyright (c) 2018-2020 Ribose Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +#.rst: +# FindBotan2 +# ----------- +# +# Find the botan-2 library. +# +# IMPORTED Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines :prop_tgt:`IMPORTED` targets: +# +# ``Botan2::Botan2`` +# The botan-2 library, if found. +# +# Result variables +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following variables: +# +# :: +# +# BOTAN2_FOUND - true if the headers and library were found +# BOTAN2_INCLUDE_DIRS - where to find headers +# BOTAN2_LIBRARIES - list of libraries to link +# BOTAN2_VERSION - library version that was found, if any + +# use pkg-config to get the directories and then use these values +# in the find_path() and find_library() calls +find_package(PkgConfig QUIET) +pkg_check_modules(PC_BOTAN2 QUIET botan-2) + +# find the headers +find_path(BOTAN2_INCLUDE_DIR + NAMES botan/version.h + HINTS + ${PC_BOTAN2_INCLUDEDIR} + ${PC_BOTAN2_INCLUDE_DIRS} + PATH_SUFFIXES botan-2 +) + +# find the library +if(MSVC) + find_library(BOTAN2_LIBRARY + NAMES botan + HINTS + ${PC_BOTAN2_LIBDIR} + ${PC_BOTAN2_LIBRARY_DIRS} + ) +else() + find_library(BOTAN2_LIBRARY + NAMES botan-2 libbotan-2 + HINTS + ${PC_BOTAN2_LIBDIR} + ${PC_BOTAN2_LIBRARY_DIRS} + ) +endif() + +# determine the version +if(PC_BOTAN2_VERSION) + set(BOTAN2_VERSION ${PC_BOTAN2_VERSION}) +elseif(BOTAN2_INCLUDE_DIR AND EXISTS "${BOTAN2_INCLUDE_DIR}/botan/build.h") + file(STRINGS "${BOTAN2_INCLUDE_DIR}/botan/build.h" botan2_version_str + REGEX "^#define[\t ]+(BOTAN_VERSION_[A-Z]+)[\t ]+[0-9]+") + + string(REGEX REPLACE ".*#define[\t ]+BOTAN_VERSION_MAJOR[\t ]+([0-9]+).*" + "\\1" _botan2_version_major "${botan2_version_str}") + string(REGEX REPLACE ".*#define[\t ]+BOTAN_VERSION_MINOR[\t ]+([0-9]+).*" + "\\1" _botan2_version_minor "${botan2_version_str}") + string(REGEX REPLACE ".*#define[\t ]+BOTAN_VERSION_PATCH[\t ]+([0-9]+).*" + "\\1" _botan2_version_patch "${botan2_version_str}") + set(BOTAN2_VERSION "${_botan2_version_major}.${_botan2_version_minor}.${_botan2_version_patch}" + CACHE INTERNAL "The version of Botan which was detected") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Botan2 + REQUIRED_VARS BOTAN2_LIBRARY BOTAN2_INCLUDE_DIR + VERSION_VAR BOTAN2_VERSION +) + +if (BOTAN2_FOUND) + set(BOTAN2_INCLUDE_DIRS ${BOTAN2_INCLUDE_DIR} ${PC_BOTAN2_INCLUDE_DIRS}) + set(BOTAN2_LIBRARIES ${BOTAN2_LIBRARY}) +endif() + +if (BOTAN2_FOUND AND NOT TARGET Botan2::Botan2) + # create the new library target + add_library(Botan2::Botan2 UNKNOWN IMPORTED) + # set the required include dirs for the target + if (BOTAN2_INCLUDE_DIRS) + set_target_properties(Botan2::Botan2 + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${BOTAN2_INCLUDE_DIRS}" + ) + endif() + # set the required libraries for the target + if (EXISTS "${BOTAN2_LIBRARY}") + set_target_properties(Botan2::Botan2 + PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${BOTAN2_LIBRARY}" + ) + endif() +endif() + +mark_as_advanced(BOTAN2_INCLUDE_DIR BOTAN2_LIBRARY) + diff --git a/cmake/Modules/FindGnuPG.cmake b/cmake/Modules/FindGnuPG.cmake new file mode 100644 index 0000000..ed92027 --- /dev/null +++ b/cmake/Modules/FindGnuPG.cmake @@ -0,0 +1,137 @@ +# Copyright (c) 2018 Ribose Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +#.rst: +# FindGnuPG +# ----------- +# +# Find GnuPG executables. +# +# Imported targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following :prop_tgt:`IMPORTED` targets: +# +# :: +# +# GnuPG::<COMPONENT> - the component executable that was requested (default is just 'gpg') +# +## Result variables +# ^^^^^^^^^^^^^^^^ +# +# This module always defines the following variables: +# +# :: +# +# GNUPG_VERSION - version that was found +# +# Depending on components requested, this module will also define variables like: +# +# :: +# +# GPG_EXECUTABLE - path to the gpg executable +# <COMPONENT>_EXECUTABLE - path to the component executable +# + +# helper that will call <utility_name> --version and extract the version string +function(_get_gpg_version utility_name exe_path var_prefix) + execute_process( + COMMAND "${exe_path}" --version + OUTPUT_VARIABLE version + RESULT_VARIABLE exit_code + ERROR_QUIET + ) + if (NOT exit_code) + string(REGEX MATCH "${utility_name} \\(GnuPG\\) (([0-9]+)\\.([0-9]+)\\.([0-9]+))" version "${version}") + if (CMAKE_MATCH_1) + set(${var_prefix}_VERSION "${CMAKE_MATCH_1}" PARENT_SCOPE) + endif() + endif() +endfunction() + +# default to finding gpg +if (NOT GnuPG_FIND_COMPONENTS) + set(GnuPG_FIND_COMPONENTS gpg) +endif() + +foreach(_comp IN LISTS GnuPG_FIND_COMPONENTS) + # we also check for an executable with the 2 suffix when appropriate + set(_names "${_comp}") + if (_comp STREQUAL "gpg" OR _comp STREQUAL "gpgv") + if (NOT ${GnuPG_FIND_VERSION}) + set(_names "${_comp}2" ${_comp}) + elseif (${GnuPG_FIND_VERSION} VERSION_GREATER_EQUAL 2.2) + # 2.2+ defaults to gpg/gpgv, but supports gpg2/gpgv2 + set(_names ${_comp} "${_comp}2") + elseif(${GnuPG_FIND_VERSION} VERSION_GREATER_EQUAL 2.0) + # 2.0-2.2 or so used a temporary naming of gpg2/gpgv2 + set(_names "${_comp}2" ${_comp}) + endif() + endif() + string(TOUPPER "${_comp}" _comp_upper) + find_program(${_comp_upper}_EXECUTABLE NAMES ${_names}) + unset(_names) + mark_as_advanced(${_comp_upper}_EXECUTABLE) + + # if we found an executable, check the version + if (${_comp_upper}_EXECUTABLE) + _get_gpg_version(${_comp} ${${_comp_upper}_EXECUTABLE} _${_comp}) + if (_${_comp}_VERSION) + if (NOT GNUPG_VERSION) + # this is the first component found, so set the version to match + set(GNUPG_VERSION ${_${_comp}_VERSION}) + endif() + # see if the version matches the previous components found + if(_${_comp}_VERSION VERSION_EQUAL ${GNUPG_VERSION} AND NOT TARGET GnuPG::${_comp}) + add_executable(GnuPG::${_comp} IMPORTED GLOBAL) + set_target_properties(GnuPG::${_comp} PROPERTIES + IMPORTED_LOCATION "${${_comp_upper}_EXECUTABLE}" + ) + endif() + endif() + unset(_${_comp}_VERSION) + endif() + + # mark our components as found or not found + if (TARGET GnuPG::${_comp}) + set(GnuPG_${_comp}_FOUND TRUE) + else() + set(GnuPG_${_comp}_FOUND FALSE) + unset(${_comp_upper}_EXECUTABLE) + endif() + + if (GnuPG_FIND_REQUIRED_${_comp}) + list(APPEND _GnuPG_REQUIRED_VARS ${_comp_upper}_EXECUTABLE) + endif() +endforeach() +unset(_comp) +unset(_comp_upper) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GnuPG + REQUIRED_VARS ${_GnuPG_REQUIRED_VARS} + VERSION_VAR GNUPG_VERSION + HANDLE_COMPONENTS +) + diff --git a/cmake/Modules/FindJSON-C.cmake b/cmake/Modules/FindJSON-C.cmake new file mode 100644 index 0000000..e66a011 --- /dev/null +++ b/cmake/Modules/FindJSON-C.cmake @@ -0,0 +1,123 @@ +# Copyright (c) 2018 Ribose Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +#.rst: +# FindJSON-C +# ----------- +# +# Find the json-c library. +# +# IMPORTED Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines :prop_tgt:`IMPORTED` targets: +# +# ``JSON-C::JSON-C`` +# The json-c library, if found. +# +# Result variables +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following variables: +# +# :: +# +# JSON-C_FOUND - true if the headers and library were found +# JSON-C_INCLUDE_DIRS - where to find headers +# JSON-C_LIBRARIES - list of libraries to link +# JSON-C_VERSION - library version that was found, if any + +# use pkg-config to get the directories and then use these values +# in the find_path() and find_library() calls +find_package(PkgConfig QUIET) +pkg_check_modules(PC_JSON-C QUIET json-c) + +# RHEL-based systems may have json-c12 +if (NOT PC_JSON-C_FOUND) + pkg_check_modules(PC_JSON-C QUIET json-c12) +endif() + +# find the headers +find_path(JSON-C_INCLUDE_DIR + NAMES json_c_version.h + HINTS + ${PC_JSON-C_INCLUDEDIR} + ${PC_JSON-C_INCLUDE_DIRS} + PATH_SUFFIXES json-c +) + +# find the library +find_library(JSON-C_LIBRARY + NAMES json-c libjson-c json-c12 libjson-c12 + HINTS + ${PC_JSON-C_LIBDIR} + ${PC_JSON-C_LIBRARY_DIRS} +) + +# determine the version +if(PC_JSON-C_VERSION) + set(JSON-C_VERSION ${PC_JSON-C_VERSION}) +elseif(JSON-C_INCLUDE_DIR AND EXISTS "${JSON-C_INCLUDE_DIR}/json_c_version.h") + file(STRINGS "${JSON-C_INCLUDE_DIR}/json_c_version.h" _json-c_version_h + REGEX "^#define[\t ]+JSON_C_VERSION[\t ]+\"[^\"]*\"$") + + string(REGEX REPLACE ".*#define[\t ]+JSON_C_VERSION[\t ]+\"([^\"]*)\".*" + "\\1" _json-c_version_str "${_json-c_version_h}") + set(JSON-C_VERSION "${_json-c_version_str}" + CACHE INTERNAL "The version of json-c which was detected") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(JSON-C + REQUIRED_VARS JSON-C_LIBRARY JSON-C_INCLUDE_DIR JSON-C_VERSION + VERSION_VAR JSON-C_VERSION +) + +if (JSON-C_FOUND) + set(JSON-C_INCLUDE_DIRS ${JSON-C_INCLUDE_DIR} ${PC_JSON-C_INCLUDE_DIRS}) + set(JSON-C_LIBRARIES ${JSON-C_LIBRARY}) +endif() + +if (JSON-C_FOUND AND NOT TARGET JSON-C::JSON-C) + # create the new library target + add_library(JSON-C::JSON-C UNKNOWN IMPORTED) + # set the required include dirs for the target + if (JSON-C_INCLUDE_DIRS) + set_target_properties(JSON-C::JSON-C + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${JSON-C_INCLUDE_DIRS}" + ) + endif() + # set the required libraries for the target + if (EXISTS "${JSON-C_LIBRARY}") + set_target_properties(JSON-C::JSON-C + PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${JSON-C_LIBRARY}" + ) + endif() +endif() + +mark_as_advanced(JSON-C_INCLUDE_DIR JSON-C_LIBRARY) + diff --git a/cmake/Modules/FindOpenSSLFeatures.cmake b/cmake/Modules/FindOpenSSLFeatures.cmake new file mode 100644 index 0000000..6967764 --- /dev/null +++ b/cmake/Modules/FindOpenSSLFeatures.cmake @@ -0,0 +1,171 @@ +# Copyright (c) 2021 Ribose Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +#.rst: +# FindOpenSSLFeatures +# ----------- +# +# Find OpenSSL features: supported hashes, ciphers, curves and public-key algorithms. +# Requires FindOpenSSL to be included first, and C compiler to be set as module +# compiles and executes program which do checks against installed OpenSSL library. +# +# Result variables +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following variables: +# +# :: +# +# OPENSSL_SUPPORTED_HASHES - list of the supported hash algorithms +# OPENSSL_SUPPORTED_CIPHERS - list of the supported ciphers +# OPENSSL_SUPPORTED_CURVES - list of the supported elliptic curves +# OPENSSL_SUPPORTED_PUBLICKEY - list of the supported public-key algorithms +# OPENSSL_SUPPORTED_FEATURES - all previous lists, glued together +# +# Functions +# ^^^^^^^^^ +# OpenSSLHasFeature(FEATURE <VARIABLE>) +# Check whether OpenSSL has corresponding feature (hash/curve/public-key algorithm name, elliptic curve). +# Result is stored in VARIABLE as boolean value, i.e. TRUE or FALSE +# +if (NOT OPENSSL_FOUND) + message(FATAL_ERROR "OpenSSL is not found. Please make sure that you call find_package(OpenSSL) first.") +endif() + +message(STATUS "Querying OpenSSL features") + +# Copy and build findopensslfeatures.c in fossl-build subfolder. +set(_fossl_work_dir "${CMAKE_BINARY_DIR}/fossl") +file(MAKE_DIRECTORY "${_fossl_work_dir}") +file(COPY "${CMAKE_CURRENT_LIST_DIR}/findopensslfeatures.c" + DESTINATION "${_fossl_work_dir}" +) +# As it's short enough let's keep it here. +# Reuse OPENSSL parameters from the upstream project +# otherwise there is a good chance to find another instance of openssl +# We assume that OpenSSL root is one level up openssl include directory +# This does not look as a good solution, however it is the only one that +# works with all Windows configuration options + +message(STATUS "Using OpenSSL root directory at ${OPENSSL_INCLUDE_DIR}/..") + +file(WRITE "${_fossl_work_dir}/CMakeLists.txt" +"cmake_minimum_required(VERSION 3.18)\n\ +project(findopensslfeatures LANGUAGES C)\n\ +set(CMAKE_C_STANDARD 99)\n\ +include(FindOpenSSL)\n\ +find_package(OpenSSL REQUIRED)\n\ +add_executable(findopensslfeatures findopensslfeatures.c)\n\ +target_include_directories(findopensslfeatures PRIVATE ${OPENSSL_INCLUDE_DIR})\n\ +target_link_libraries(findopensslfeatures PRIVATE OpenSSL::Crypto)\n\ +if (OpenSSL::applink)\n\ + target_link_libraries(findopensslfeatures PRIVATE OpenSSL::applink)\n\ +endif(OpenSSL::applink)\n" +) + +set(MKF ${MKF} "-DCMAKE_BUILD_TYPE=Release" "-DOPENSSL_ROOT_DIR=${OPENSSL_INCLUDE_DIR}/..") + +if(CMAKE_PREFIX_PATH) + set(MKF ${MKF} "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}") +endif(CMAKE_PREFIX_PATH) + +if(CMAKE_TOOLCHAIN_FILE) + set(MKF ${MKF} "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}") +endif(CMAKE_TOOLCHAIN_FILE) + +if(CMAKE_GENERATOR_PLATFORM) + set(MKF ${MKF} "-A" "${CMAKE_GENERATOR_PLATFORM}") +endif(CMAKE_GENERATOR_PLATFORM) + +if(CMAKE_GENERATOR_TOOLSET) + set(MKF ${MKF} "-T" "${CMAKE_GENERATOR_TOOLSET}") +endif(CMAKE_GENERATOR_TOOLSET) + +execute_process( + COMMAND "${CMAKE_COMMAND}" "-Bbuild" ${MKF} "." + WORKING_DIRECTORY "${_fossl_work_dir}" + OUTPUT_VARIABLE output + ERROR_VARIABLE error + RESULT_VARIABLE result + COMMAND_ECHO STDOUT + ECHO_OUTPUT_VARIABLE + ECHO_ERROR_VARIABLE +) + +if (NOT ${result} EQUAL 0) + message(FATAL_ERROR "Error configuring findopensslfeatures") +endif() + +execute_process( + COMMAND "${CMAKE_COMMAND}" "--build" "build" --config "Release" + WORKING_DIRECTORY "${_fossl_work_dir}" + OUTPUT_VARIABLE output + ERROR_VARIABLE error + RESULT_VARIABLE result + COMMAND_ECHO STDOUT + ECHO_OUTPUT_VARIABLE + ECHO_ERROR_VARIABLE +) + +if (NOT ${result} EQUAL 0) + message(FATAL_ERROR "Error building findopensslfeatures") +endif() + +set(OPENSSL_SUPPORTED_FEATURES "") +if(WIN32 AND NOT MINGW) + set(FOF "build/Release/findopensslfeatures") +else(WIN32 AND NOT MINGW) + set(FOF "build/findopensslfeatures") +endif(WIN32 AND NOT MINGW) + +foreach(feature "hashes" "ciphers" "curves" "publickey") + execute_process( + COMMAND "${FOF}" "${feature}" + WORKING_DIRECTORY "${_fossl_work_dir}" + OUTPUT_VARIABLE feature_val + ERROR_VARIABLE error + RESULT_VARIABLE result + ) + + if(NOT ${result} EQUAL 0) + message(FATAL_ERROR "Error getting supported OpenSSL ${feature}: ${result}\n${error}") + endif() + + string(TOUPPER ${feature} feature_up) + string(TOUPPER ${feature_val} feature_val) + string(REPLACE "\n" ";" feature_val ${feature_val}) + set(OPENSSL_SUPPORTED_${feature_up} ${feature_val}) + list(LENGTH OPENSSL_SUPPORTED_${feature_up} ${feature}_len) + list(APPEND OPENSSL_SUPPORTED_FEATURES ${OPENSSL_SUPPORTED_${feature_up}}) +endforeach() + +message(STATUS "Fetched OpenSSL features: ${hashes_len} hashes, ${ciphers_len} ciphers, ${curves_len} curves, ${publickey_len} publickey.") + +function(OpenSSLHasFeature FEATURE VARIABLE) + string(TOUPPER ${FEATURE} _feature_up) + set(${VARIABLE} FALSE PARENT_SCOPE) + if (${_feature_up} IN_LIST OPENSSL_SUPPORTED_FEATURES) + set(${VARIABLE} TRUE PARENT_SCOPE) + endif() +endfunction(OpenSSLHasFeature) diff --git a/cmake/Modules/FindWindowsSDK.cmake b/cmake/Modules/FindWindowsSDK.cmake new file mode 100644 index 0000000..d18e979 --- /dev/null +++ b/cmake/Modules/FindWindowsSDK.cmake @@ -0,0 +1,662 @@ +# - Find the Windows SDK aka Platform SDK +# taken from https://github.com/ampl/mp/blob/master/support/cmake/FindWindowsSDK.cmake +# +# Relevant Wikipedia article: http://en.wikipedia.org/wiki/Microsoft_Windows_SDK +# +# Pass "COMPONENTS tools" to ignore Visual Studio version checks: in case +# you just want the tool binaries to run, rather than the libraries and headers +# for compiling. +# +# Variables: +# WINDOWSSDK_FOUND - if any version of the windows or platform SDK was found that is usable with the current version of visual studio +# WINDOWSSDK_LATEST_DIR +# WINDOWSSDK_LATEST_NAME +# WINDOWSSDK_FOUND_PREFERENCE - if we found an entry indicating a "preferred" SDK listed for this visual studio version +# WINDOWSSDK_PREFERRED_DIR +# WINDOWSSDK_PREFERRED_NAME +# +# WINDOWSSDK_DIRS - contains no duplicates, ordered most recent first. +# WINDOWSSDK_PREFERRED_FIRST_DIRS - contains no duplicates, ordered with preferred first, followed by the rest in descending recency +# +# Functions: +# GetUMWindowsSDKLibraryDir(<output variable>) - Find the latest SDK user mode (um) library directory, +# architecture dependent +# GetUMWindowsSDKIncludeDir(<output variable>) - Find the latest SDK user mode (um) include directory +# +# windowssdk_name_lookup(<directory> <output variable>) - Find the name corresponding with the SDK directory you pass in, or +# NOTFOUND if not recognized. Your directory must be one of WINDOWSSDK_DIRS for this to work. +# +# windowssdk_build_lookup(<directory> <output variable>) - Find the build version number corresponding with the SDK directory you pass in, or +# NOTFOUND if not recognized. Your directory must be one of WINDOWSSDK_DIRS for this to work. +# +# get_windowssdk_from_component(<file or dir> <output variable>) - Given a library or include dir, +# find the Windows SDK root dir corresponding to it, or NOTFOUND if unrecognized. +# +# get_windowssdk_library_dirs(<directory> <output variable>) - Find the architecture-appropriate +# library directories corresponding to the SDK directory you pass in (or NOTFOUND if none) +# +# get_windowssdk_library_dirs_multiple(<output variable> <directory> ...) - Find the architecture-appropriate +# library directories corresponding to the SDK directories you pass in, in order, skipping those not found. NOTFOUND if none at all. +# Good for passing WINDOWSSDK_DIRS or WINDOWSSDK_DIRS to if you really just want a file and don't care where from. +# +# get_windowssdk_include_dirs(<directory> <output variable>) - Find the +# include directories corresponding to the SDK directory you pass in (or NOTFOUND if none) +# +# get_windowssdk_include_dirs_multiple(<output variable> <directory> ...) - Find the +# include directories corresponding to the SDK directories you pass in, in order, skipping those not found. NOTFOUND if none at all. +# Good for passing WINDOWSSDK_DIRS or WINDOWSSDK_DIRS to if you really just want a file and don't care where from. +# +# Requires these CMake modules: +# FindPackageHandleStandardArgs (known included with CMake >=2.6.2) +# +# Original Author: +# 2012 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net> +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2012. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(_preferred_sdk_dirs) # pre-output +set(_win_sdk_dirs) # pre-output +set(_win_sdk_versanddirs) # pre-output +set(_win_sdk_buildsanddirs) # pre-output +set(_winsdk_vistaonly) # search parameters +set(_winsdk_kits) # search parameters + + +set(_WINDOWSSDK_ANNOUNCE OFF) +if(NOT WINDOWSSDK_FOUND AND (NOT WindowsSDK_FIND_QUIETLY)) + set(_WINDOWSSDK_ANNOUNCE ON) +endif() +macro(_winsdk_announce) + if(_WINSDK_ANNOUNCE) + message(STATUS ${ARGN}) + endif() +endmacro() + + +set(_winsdk_win10vers + 10.0.18362.0 # Windows 10 SDK for 2019 Update + 10.0.17763.0 # Windows 10 SDK for October 2018 Update + 10.0.17133.0 # Redstone 4 aka Win10 1803 "April 1018 Update" + 10.0.16299.0 # Redstone 3 aka Win10 1709 "Fall Creators Update" + 10.0.15063.0 # Redstone 2 aka Win10 1703 "Creators Update" + 10.0.14393.0 # Redstone aka Win10 1607 "Anniversary Update" + 10.0.10586.0 # TH2 aka Win10 1511 + 10.0.10240.0 # Win10 RTM + 10.0.10150.0 # just ucrt + 10.0.10056.0 +) + +if(WindowsSDK_FIND_COMPONENTS MATCHES "tools") + set(_WINDOWSSDK_IGNOREMSVC ON) + _winsdk_announce("Checking for tools from Windows/Platform SDKs...") +else() + set(_WINDOWSSDK_IGNOREMSVC OFF) + _winsdk_announce("Checking for Windows/Platform SDKs...") +endif() + +# Appends to the three main pre-output lists used only if the path exists +# and is not already in the list. +function(_winsdk_conditional_append _vername _build _path) + if(("${_path}" MATCHES "registry") OR (NOT EXISTS "${_path}")) + # Path invalid - do not add + return() + endif() + list(FIND _win_sdk_dirs "${_path}" _win_sdk_idx) + if(_win_sdk_idx GREATER -1) + # Path already in list - do not add + return() + endif() + _winsdk_announce( " - ${_vername}, Build ${_build} @ ${_path}") + # Not yet in the list, so we'll add it + list(APPEND _win_sdk_dirs "${_path}") + set(_win_sdk_dirs "${_win_sdk_dirs}" CACHE INTERNAL "" FORCE) + list(APPEND + _win_sdk_versanddirs + "${_vername}" + "${_path}") + set(_win_sdk_versanddirs "${_win_sdk_versanddirs}" CACHE INTERNAL "" FORCE) + list(APPEND + _win_sdk_buildsanddirs + "${_build}" + "${_path}") + set(_win_sdk_buildsanddirs "${_win_sdk_buildsanddirs}" CACHE INTERNAL "" FORCE) +endfunction() + +# Appends to the "preferred SDK" lists only if the path exists +function(_winsdk_conditional_append_preferred _info _path) + if(("${_path}" MATCHES "registry") OR (NOT EXISTS "${_path}")) + # Path invalid - do not add + return() + endif() + + get_filename_component(_path "${_path}" ABSOLUTE) + + list(FIND _win_sdk_preferred_sdk_dirs "${_path}" _win_sdk_idx) + if(_win_sdk_idx GREATER -1) + # Path already in list - do not add + return() + endif() + _winsdk_announce( " - Found \"preferred\" SDK ${_info} @ ${_path}") + # Not yet in the list, so we'll add it + list(APPEND _win_sdk_preferred_sdk_dirs "${_path}") + set(_win_sdk_preferred_sdk_dirs "${_win_sdk_dirs}" CACHE INTERNAL "" FORCE) + + # Just in case we somehow missed it: + _winsdk_conditional_append("${_info}" "" "${_path}") +endfunction() + +# Given a version like v7.0A, looks for an SDK in the registry under "Microsoft SDKs". +# If the given version might be in both HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows +# and HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots aka "Windows Kits", +# use this macro first, since these registry keys usually have more information. +# +# Pass a "default" build number as an extra argument in case we can't find it. +function(_winsdk_check_microsoft_sdks_registry _winsdkver) + set(SDKKEY "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\${_winsdkver}") + get_filename_component(_sdkdir + "[${SDKKEY};InstallationFolder]" + ABSOLUTE) + + set(_sdkname "Windows SDK ${_winsdkver}") + + # Default build number passed as extra argument + set(_build ${ARGN}) + # See if the registry holds a Microsoft-mutilated, err, designated, product name + # (just using get_filename_component to execute the registry lookup) + get_filename_component(_sdkproductname + "[${SDKKEY};ProductName]" + NAME) + if(NOT "${_sdkproductname}" MATCHES "registry") + # Got a product name + set(_sdkname "${_sdkname} (${_sdkproductname})") + endif() + + # try for a version to augment our name + # (just using get_filename_component to execute the registry lookup) + get_filename_component(_sdkver + "[${SDKKEY};ProductVersion]" + NAME) + if(NOT "${_sdkver}" MATCHES "registry" AND NOT MATCHES) + # Got a version + if(NOT "${_sdkver}" MATCHES "\\.\\.") + # and it's not an invalid one with two dots in it: + # use to override the default build + set(_build ${_sdkver}) + if(NOT "${_sdkname}" MATCHES "${_sdkver}") + # Got a version that's not already in the name, let's use it to improve our name. + set(_sdkname "${_sdkname} (${_sdkver})") + endif() + endif() + endif() + _winsdk_conditional_append("${_sdkname}" "${_build}" "${_sdkdir}") +endfunction() + +# Given a name for identification purposes, the build number, and a key (technically a "value name") +# corresponding to a Windows SDK packaged as a "Windows Kit", look for it +# in HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots +# Note that the key or "value name" tends to be something weird like KitsRoot81 - +# no easy way to predict, just have to observe them in the wild. +# Doesn't hurt to also try _winsdk_check_microsoft_sdks_registry for these: +# sometimes you get keys in both parts of the registry (in the wow64 portion especially), +# and the non-"Windows Kits" location is often more descriptive. +function(_winsdk_check_windows_kits_registry _winkit_name _winkit_build _winkit_key) + get_filename_component(_sdkdir + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;${_winkit_key}]" + ABSOLUTE) + _winsdk_conditional_append("${_winkit_name}" "${_winkit_build}" "${_sdkdir}") +endfunction() + +# Given a name for identification purposes and the build number +# corresponding to a Windows 10 SDK packaged as a "Windows Kit", look for it +# in HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots +# Doesn't hurt to also try _winsdk_check_microsoft_sdks_registry for these: +# sometimes you get keys in both parts of the registry (in the wow64 portion especially), +# and the non-"Windows Kits" location is often more descriptive. +function(_winsdk_check_win10_kits _winkit_build) + get_filename_component(_sdkdir + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot10]" + ABSOLUTE) + if(("${_sdkdir}" MATCHES "registry") OR (NOT EXISTS "${_sdkdir}")) + return() # not found + endif() + if(EXISTS "${_sdkdir}/Include/${_winkit_build}/um") + _winsdk_conditional_append("Windows Kits 10 (Build ${_winkit_build})" "${_winkit_build}" "${_sdkdir}") + endif() +endfunction() + +# Given a name for identification purposes, the build number, and the associated package GUID, +# look in the registry under both HKLM and HKCU in \\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\ +# for that guid and the SDK it points to. +function(_winsdk_check_platformsdk_registry _platformsdkname _build _platformsdkguid) + foreach(_winsdk_hive HKEY_LOCAL_MACHINE HKEY_CURRENT_USER) + get_filename_component(_sdkdir + "[${_winsdk_hive}\\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\${_platformsdkguid};Install Dir]" + ABSOLUTE) + _winsdk_conditional_append("${_platformsdkname} (${_build})" "${_build}" "${_sdkdir}") + endforeach() +endfunction() + +### +# Detect toolchain information: to know whether it's OK to use Vista+ only SDKs +### +set(_winsdk_vistaonly_ok OFF) +if(MSVC AND NOT _WINDOWSSDK_IGNOREMSVC) + # VC 10 and older has broad target support + if(MSVC_VERSION LESS 1700) + # VC 11 by default targets Vista and later only, so we can add a few more SDKs that (might?) only work on vista+ + elseif("${CMAKE_VS_PLATFORM_TOOLSET}" MATCHES "_xp") + # This is the XP-compatible v110+ toolset + elseif("${CMAKE_VS_PLATFORM_TOOLSET}" STREQUAL "v100" OR "${CMAKE_VS_PLATFORM_TOOLSET}" STREQUAL "v90") + # This is the VS2010/VS2008 toolset + else() + # OK, we're VC11 or newer and not using a backlevel or XP-compatible toolset. + # These versions have no XP (and possibly Vista pre-SP1) support + set(_winsdk_vistaonly_ok ON) + if(_WINDOWSSDK_ANNOUNCE AND NOT _WINDOWSSDK_VISTAONLY_PESTERED) + set(_WINDOWSSDK_VISTAONLY_PESTERED ON CACHE INTERNAL "" FORCE) + message(STATUS "FindWindowsSDK: Detected Visual Studio 2012 or newer, not using the _xp toolset variant: including SDK versions that drop XP support in search!") + endif() + endif() +endif() +if(_WINDOWSSDK_IGNOREMSVC) + set(_winsdk_vistaonly_ok ON) +endif() + +### +# MSVC version checks - keeps messy conditionals in one place +# (messy because of _WINDOWSSDK_IGNOREMSVC) +### +set(_winsdk_msvc_greater_1200 OFF) +if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (MSVC_VERSION GREATER 1200))) + set(_winsdk_msvc_greater_1200 ON) +endif() +# Newer than VS .NET/VS Toolkit 2003 +set(_winsdk_msvc_greater_1310 OFF) +if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (MSVC_VERSION GREATER 1310))) + set(_winsdk_msvc_greater_1310 ON) +endif() + +# VS2005/2008 +set(_winsdk_msvc_less_1600 OFF) +if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (MSVC_VERSION LESS 1600))) + set(_winsdk_msvc_less_1600 ON) +endif() + +# VS2013+ +set(_winsdk_msvc_not_less_1800 OFF) +if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (NOT MSVC_VERSION LESS 1800))) + set(_winsdk_msvc_not_less_1800 ON) +endif() + +### +# START body of find module +### +if(_winsdk_msvc_greater_1310) # Newer than VS .NET/VS Toolkit 2003 + ### + # Look for "preferred" SDKs + ### + + # Environment variable for SDK dir + if(EXISTS "$ENV{WindowsSDKDir}" AND (NOT "$ENV{WindowsSDKDir}" STREQUAL "")) + _winsdk_conditional_append_preferred("WindowsSDKDir environment variable" "$ENV{WindowsSDKDir}") + endif() + + if(_winsdk_msvc_less_1600) + # Per-user current Windows SDK for VS2005/2008 + get_filename_component(_sdkdir + "[HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" + ABSOLUTE) + _winsdk_conditional_append_preferred("Per-user current Windows SDK" "${_sdkdir}") + + # System-wide current Windows SDK for VS2005/2008 + get_filename_component(_sdkdir + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" + ABSOLUTE) + _winsdk_conditional_append_preferred("System-wide current Windows SDK" "${_sdkdir}") + endif() + + ### + # Begin the massive list of SDK searching! + ### + if(_winsdk_vistaonly_ok AND _winsdk_msvc_not_less_1800) + # These require at least Visual Studio 2013 (VC12) + + _winsdk_check_microsoft_sdks_registry(v10.0A) + + # Windows Software Development Kit (SDK) for Windows 10 + # Several different versions living in the same directory - if nothing else we can assume RTM (10240) + _winsdk_check_microsoft_sdks_registry(v10.0 10.0.10240.0) + foreach(_win10build ${_winsdk_win10vers}) + _winsdk_check_win10_kits(${_win10build}) + endforeach() + endif() # vista-only and 2013+ + + # Included in Visual Studio 2013 + # Includes the v120_xp toolset + _winsdk_check_microsoft_sdks_registry(v8.1A 8.1.51636) + + if(_winsdk_vistaonly_ok AND _winsdk_msvc_not_less_1800) + # Windows Software Development Kit (SDK) for Windows 8.1 + # http://msdn.microsoft.com/en-gb/windows/desktop/bg162891 + _winsdk_check_microsoft_sdks_registry(v8.1 8.1.25984.0) + _winsdk_check_windows_kits_registry("Windows Kits 8.1" 8.1.25984.0 KitsRoot81) + endif() # vista-only and 2013+ + + if(_winsdk_vistaonly_ok) + # Included in Visual Studio 2012 + _winsdk_check_microsoft_sdks_registry(v8.0A 8.0.50727) + + # Microsoft Windows SDK for Windows 8 and .NET Framework 4.5 + # This is the first version to also include the DirectX SDK + # http://msdn.microsoft.com/en-US/windows/desktop/hh852363.aspx + _winsdk_check_microsoft_sdks_registry(v8.0 6.2.9200.16384) + _winsdk_check_windows_kits_registry("Windows Kits 8.0" 6.2.9200.16384 KitsRoot) + endif() # vista-only + + # Included with VS 2012 Update 1 or later + # Introduces v110_xp toolset + _winsdk_check_microsoft_sdks_registry(v7.1A 7.1.51106) + if(_winsdk_vistaonly_ok) + # Microsoft Windows SDK for Windows 7 and .NET Framework 4 + # http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b + _winsdk_check_microsoft_sdks_registry(v7.1 7.1.7600.0.30514) + endif() # vista-only + + # Included with VS 2010 + _winsdk_check_microsoft_sdks_registry(v7.0A 6.1.7600.16385) + + # Windows SDK for Windows 7 and .NET Framework 3.5 SP1 + # Works with VC9 + # http://www.microsoft.com/en-us/download/details.aspx?id=18950 + _winsdk_check_microsoft_sdks_registry(v7.0 6.1.7600.16385) + + # Two versions call themselves "v6.1": + # Older: + # Windows Vista Update & .NET 3.0 SDK + # http://www.microsoft.com/en-us/download/details.aspx?id=14477 + + # Newer: + # Windows Server 2008 & .NET 3.5 SDK + # may have broken VS9SP1? they recommend v7.0 instead, or a KB... + # http://www.microsoft.com/en-us/download/details.aspx?id=24826 + _winsdk_check_microsoft_sdks_registry(v6.1 6.1.6000.16384.10) + + # Included in VS 2008 + _winsdk_check_microsoft_sdks_registry(v6.0A 6.1.6723.1) + + # Microsoft Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Runtime Components + # http://blogs.msdn.com/b/stanley/archive/2006/11/08/microsoft-windows-software-development-kit-for-windows-vista-and-net-framework-3-0-runtime-components.aspx + _winsdk_check_microsoft_sdks_registry(v6.0 6.0.6000.16384) +endif() + +# Let's not forget the Platform SDKs, which sometimes are useful! +if(_winsdk_msvc_greater_1200) + _winsdk_check_platformsdk_registry("Microsoft Platform SDK for Windows Server 2003 R2" "5.2.3790.2075.51" "D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1") + _winsdk_check_platformsdk_registry("Microsoft Platform SDK for Windows Server 2003 SP1" "5.2.3790.1830.15" "8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3") +endif() +### +# Finally, look for "preferred" SDKs +### +if(_winsdk_msvc_greater_1310) # Newer than VS .NET/VS Toolkit 2003 + + + # Environment variable for SDK dir + if(EXISTS "$ENV{WindowsSDKDir}" AND (NOT "$ENV{WindowsSDKDir}" STREQUAL "")) + _winsdk_conditional_append_preferred("WindowsSDKDir environment variable" "$ENV{WindowsSDKDir}") + endif() + + if(_winsdk_msvc_less_1600) + # Per-user current Windows SDK for VS2005/2008 + get_filename_component(_sdkdir + "[HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" + ABSOLUTE) + _winsdk_conditional_append_preferred("Per-user current Windows SDK" "${_sdkdir}") + + # System-wide current Windows SDK for VS2005/2008 + get_filename_component(_sdkdir + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" + ABSOLUTE) + _winsdk_conditional_append_preferred("System-wide current Windows SDK" "${_sdkdir}") + endif() +endif() + + +function(windowssdk_name_lookup _dir _outvar) + list(FIND _win_sdk_versanddirs "${_dir}" _diridx) + math(EXPR _idx "${_diridx} - 1") + if(${_idx} GREATER -1) + list(GET _win_sdk_versanddirs ${_idx} _ret) + else() + set(_ret "NOTFOUND") + endif() + set(${_outvar} "${_ret}" PARENT_SCOPE) +endfunction() + +function(windowssdk_build_lookup _dir _outvar) + list(FIND _win_sdk_buildsanddirs "${_dir}" _diridx) + math(EXPR _idx "${_diridx} - 1") + if(${_idx} GREATER -1) + list(GET _win_sdk_buildsanddirs ${_idx} _ret) + else() + set(_ret "NOTFOUND") + endif() + set(${_outvar} "${_ret}" PARENT_SCOPE) +endfunction() + +# If we found something... +if(_win_sdk_dirs) + list(GET _win_sdk_dirs 0 WINDOWSSDK_LATEST_DIR) + windowssdk_name_lookup("${WINDOWSSDK_LATEST_DIR}" + WINDOWSSDK_LATEST_NAME) + set(WINDOWSSDK_DIRS ${_win_sdk_dirs}) + + # Fallback, in case no preference found. + set(WINDOWSSDK_PREFERRED_DIR "${WINDOWSSDK_LATEST_DIR}") + set(WINDOWSSDK_PREFERRED_NAME "${WINDOWSSDK_LATEST_NAME}") + set(WINDOWSSDK_PREFERRED_FIRST_DIRS ${WINDOWSSDK_DIRS}) + set(WINDOWSSDK_FOUND_PREFERENCE OFF) +endif() + +# If we found indications of a user preference... +if(_win_sdk_preferred_sdk_dirs) + list(GET _win_sdk_preferred_sdk_dirs 0 WINDOWSSDK_PREFERRED_DIR) + windowssdk_name_lookup("${WINDOWSSDK_PREFERRED_DIR}" + WINDOWSSDK_PREFERRED_NAME) + set(WINDOWSSDK_PREFERRED_FIRST_DIRS + ${_win_sdk_preferred_sdk_dirs} + ${_win_sdk_dirs}) + list(REMOVE_DUPLICATES WINDOWSSDK_PREFERRED_FIRST_DIRS) + set(WINDOWSSDK_FOUND_PREFERENCE ON) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(WindowsSDK + "No compatible version of the Windows SDK or Platform SDK found." + WINDOWSSDK_DIRS) + +if(WINDOWSSDK_FOUND) + # Internal: Architecture-appropriate library directory names. + if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "ARM") + if(CMAKE_SIZEOF_VOID_P MATCHES "8") + # Only supported in Win10 SDK and up. + set(_winsdk_arch8 arm64) # what the WDK for Win8+ calls this architecture + else() + set(_winsdk_archbare /arm) # what the architecture used to be called in oldest SDKs + set(_winsdk_arch arm) # what the architecture used to be called + set(_winsdk_arch8 arm) # what the WDK for Win8+ calls this architecture + endif() + else() + if(CMAKE_SIZEOF_VOID_P MATCHES "8") + set(_winsdk_archbare /x64) # what the architecture used to be called in oldest SDKs + set(_winsdk_arch amd64) # what the architecture used to be called + set(_winsdk_arch8 x64) # what the WDK for Win8+ calls this architecture + else() + set(_winsdk_archbare ) # what the architecture used to be called in oldest SDKs + set(_winsdk_arch i386) # what the architecture used to be called + set(_winsdk_arch8 x86) # what the WDK for Win8+ calls this architecture + endif() + endif() + + function(get_windowssdk_from_component _component _var) + get_filename_component(_component "${_component}" ABSOLUTE) + file(TO_CMAKE_PATH "${_component}" _component) + foreach(_sdkdir ${WINDOWSSDK_DIRS}) + get_filename_component(_sdkdir "${_sdkdir}" ABSOLUTE) + string(LENGTH "${_sdkdir}" _sdklen) + file(RELATIVE_PATH _rel "${_sdkdir}" "${_component}") + # If we don't have any "parent directory" items... + if(NOT "${_rel}" MATCHES "[.][.]") + set(${_var} "${_sdkdir}" PARENT_SCOPE) + return() + endif() + endforeach() + # Fail. + set(${_var} "NOTFOUND" PARENT_SCOPE) + endfunction() + function(get_windowssdk_library_dirs _winsdk_dir _var) + set(_dirs) + set(_suffixes + "lib${_winsdk_archbare}" # SDKs like 7.1A + "lib/${_winsdk_arch}" # just because some SDKs have x86 dir and root dir + "lib/w2k/${_winsdk_arch}" # Win2k min requirement + "lib/wxp/${_winsdk_arch}" # WinXP min requirement + "lib/wnet/${_winsdk_arch}" # Win Server 2003 min requirement + "lib/wlh/${_winsdk_arch}" + "lib/wlh/um/${_winsdk_arch8}" # Win Vista ("Long Horn") min requirement + "lib/win7/${_winsdk_arch}" + "lib/win7/um/${_winsdk_arch8}" # Win 7 min requirement + ) + foreach(_ver + wlh # Win Vista ("Long Horn") min requirement + win7 # Win 7 min requirement + win8 # Win 8 min requirement + winv6.3 # Win 8.1 min requirement + ) + + list(APPEND _suffixes + "lib/${_ver}/${_winsdk_arch}" + "lib/${_ver}/um/${_winsdk_arch8}" + "lib/${_ver}/km/${_winsdk_arch8}" + ) + endforeach() + + # Look for WDF libraries in Win10+ SDK + foreach(_mode umdf kmdf) + file(GLOB _wdfdirs RELATIVE "${_winsdk_dir}" "${_winsdk_dir}/lib/wdf/${_mode}/${_winsdk_arch8}/*") + if(_wdfdirs) + list(APPEND _suffixes ${_wdfdirs}) + endif() + endforeach() + + # Look in each Win10+ SDK version for the components + foreach(_win10ver ${_winsdk_win10vers}) + foreach(_component um km ucrt mmos) + list(APPEND _suffixes "lib/${_win10ver}/${_component}/${_winsdk_arch8}") + endforeach() + endforeach() + + foreach(_suffix ${_suffixes}) + # Check to see if a library actually exists here. + file(GLOB _libs "${_winsdk_dir}/${_suffix}/*.lib") + if(_libs) + list(APPEND _dirs "${_winsdk_dir}/${_suffix}") + endif() + endforeach() + if("${_dirs}" STREQUAL "") + set(_dirs NOTFOUND) + else() + list(REMOVE_DUPLICATES _dirs) + endif() + set(${_var} ${_dirs} PARENT_SCOPE) + endfunction() + function(get_windowssdk_include_dirs _winsdk_dir _var) + set(_dirs) + + set(_subdirs shared um winrt km wdf mmos ucrt) + set(_suffixes Include) + + foreach(_dir ${_subdirs}) + list(APPEND _suffixes "Include/${_dir}") + endforeach() + + foreach(_ver ${_winsdk_win10vers}) + foreach(_dir ${_subdirs}) + list(APPEND _suffixes "Include/${_ver}/${_dir}") + endforeach() + endforeach() + + foreach(_suffix ${_suffixes}) + # Check to see if a header file actually exists here. + file(GLOB _headers "${_winsdk_dir}/${_suffix}/*.h") + if(_headers) + list(APPEND _dirs "${_winsdk_dir}/${_suffix}") + endif() + endforeach() + if("${_dirs}" STREQUAL "") + set(_dirs NOTFOUND) + else() + list(REMOVE_DUPLICATES _dirs) + endif() + set(${_var} ${_dirs} PARENT_SCOPE) + endfunction() + + + + function(get_windowssdk_library_dirs_multiple _var) + set(_dirs) + foreach(_sdkdir ${ARGN}) + get_windowssdk_library_dirs("${_sdkdir}" _current_sdk_libdirs) + if(_current_sdk_libdirs) + list(APPEND _dirs ${_current_sdk_libdirs}) + endif() + endforeach() + if("${_dirs}" STREQUAL "") + set(_dirs NOTFOUND) + else() + list(REMOVE_DUPLICATES _dirs) + endif() + set(${_var} ${_dirs} PARENT_SCOPE) + endfunction() + function(get_windowssdk_include_dirs_multiple _var) + set(_dirs) + foreach(_sdkdir ${ARGN}) + get_windowssdk_include_dirs("${_sdkdir}" _current_sdk_incdirs) + if(_current_sdk_libdirs) + list(APPEND _dirs ${_current_sdk_incdirs}) + endif() + endforeach() + if("${_dirs}" STREQUAL "") + set(_dirs NOTFOUND) + else() + list(REMOVE_DUPLICATES _dirs) + endif() + set(${_var} ${_dirs} PARENT_SCOPE) + endfunction() +endif() + + +function(FindFirstStringMatching list reg matching) + foreach(l ${${list}}) + if(${l} MATCHES ${reg}) + set(${matching} ${l} PARENT_SCOPE) + break() + endif() + endforeach() +endfunction() + +function(GetUMWindowsSDKLibraryDir library_dir) + get_windowssdk_library_dirs(${WINDOWSSDK_LATEST_DIR} WIN_LIBRARY_DIRS) + FindFirstStringMatching(WIN_LIBRARY_DIRS "[\\/]um[\\/]" WINDOWSKIT_LIBRARY_DIR) + set(${library_dir} ${WINDOWSKIT_LIBRARY_DIR} PARENT_SCOPE) +endfunction() + +function(GetUMWindowsSDKIncludeDir include_dir) + get_windowssdk_include_dirs(${WINDOWSSDK_LATEST_DIR} WIN_INCLUDE_DIRS) + FindFirstStringMatching(WIN_INCLUDE_DIRS "[\\/]um[\\/]" WIN_INCLUDE_DIR) + set(${include_dir} ${WIN_INCLUDE_DIR} PARENT_SCOPE) +endfunction() diff --git a/cmake/Modules/findopensslfeatures.c b/cmake/Modules/findopensslfeatures.c new file mode 100644 index 0000000..390f1d2 --- /dev/null +++ b/cmake/Modules/findopensslfeatures.c @@ -0,0 +1,101 @@ +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <openssl/ec.h> +#include <openssl/objects.h> +#include <openssl/evp.h> + +int +list_curves() +{ + size_t len = EC_get_builtin_curves(NULL, 0); + EC_builtin_curve *curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * len); + if (!curves) { + fprintf(stderr, "Allocation failed.\n"); + return 1; + } + if (!EC_get_builtin_curves(curves, len)) { + OPENSSL_free(curves); + fprintf(stderr, "Failed to get curves.\n"); + return 1; + } + for (size_t i = 0; i < len; i++) { + const char *sname = OBJ_nid2sn(curves[i].nid); + if (!sname) { + continue; + } + printf("%s\n", sname); + } + OPENSSL_free(curves); + return 0; +} + +static void +print_hash(const EVP_MD *md, const char *from, const char *to, void *arg) +{ + if (!md) { + return; + } + if (strstr(from, "rsa") || strstr(from, "RSA")) { + return; + } + printf("%s\n", from); +} + +int +list_hashes() +{ + EVP_MD_do_all_sorted(print_hash, NULL); + return 0; +} + +static void +print_cipher(const EVP_CIPHER *cipher, const char *from, const char *to, void *x) +{ + if (!cipher) { + return; + } + printf("%s\n", from); +} + +int +list_ciphers() +{ + EVP_CIPHER_do_all_sorted(print_cipher, NULL); + return 0; +} + +int +list_publickey() +{ + for (size_t i = 0; i < EVP_PKEY_meth_get_count(); i++) { + const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i); + int id = 0; + EVP_PKEY_meth_get0_info(&id, NULL, pmeth); + printf("%s\n", OBJ_nid2ln(id)); + } + return 0; +} + +int +main(int argc, char *argv[]) +{ + if (argc != 2) { + fprintf(stderr, "Usage: opensslfeatures [curves|hashes|ciphers|publickey]\n"); + return 1; + } + if (!strcmp(argv[1], "hashes")) { + return list_hashes(); + } + if (!strcmp(argv[1], "ciphers")) { + return list_ciphers(); + } + if (!strcmp(argv[1], "curves")) { + return list_curves(); + } + if (!strcmp(argv[1], "publickey")) { + return list_publickey(); + } + fprintf(stderr, "Unknown command: %s\n", argv[1]); + return 1; +} |