Files
soci/cmake/soci_utils.cmake
Vadim Zeitlin a2f8d61242 Get rid of SOCI_INT8_T_IS_CHAR too
As we can't specialize exchange_traits<> for both int8_t and char when
they are the same type (which is the case under Solaris, see #1154),
specialize exchange_traits<> for some wrapper type in this case to avoid
compilation errors.

This is an alternative, and simpler, solution than that of #1170, so we
can now remove soci_are_types_same CMake function.
2025-06-13 01:31:08 +02:00

141 lines
5.2 KiB
CMake

# This function is meant to be called by other cmake functions that use the cmake_parse_arguments function.
# It implements the boilerplate that is associated with validating the parsed arguments (e.g. no unknown arguments used;
# ensuring all required options have been set).
#
# Use as
# soci_verify_parsed_arguments(
# PREFIX <prefix>
# FUNCTION_NAME <name>
# [REQUIRED <option1> <option2> …]
# )
# where
# - <prefix> is the prefix used in the cmake_parse_arguments call that shall be validated
# - <name> is the name of the calling function or macro - this will be part of error mesages
# - <optionN> are names of options **without** the prefix
function(soci_verify_parsed_arguments)
set(FLAGS "")
set(ONE_VAL_OPTIONS "PREFIX" "FUNCTION_NAME")
set(MULTI_VAL_OPTIONS "REQUIRED")
cmake_parse_arguments(VERIFY_PARSED_ARGS "${FLAGS}" "${ONE_VAL_OPTIONS}" "${MULTI_VAL_OPTIONS}" ${ARGV})
# First, verify own arguments
if (DEFINED VERIFY_PARSED_ARGS_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "verify_parsed_arguments - Received unrecognized options: ${VERIFY_PARSED_ARGS_UNPARSED_ARGUMENTS}")
endif()
if (DEFINED VERIFY_PARSED_ARGS_KEYWORDS_MISSING_VALUES)
message(FATAL_ERROR "verify_parsed_arguments - The following options are missing argumens: ${VERIFY_PARSED_ARGS_KEYWORDS_MISSING_VALUES}")
endif()
if (NOT DEFINED VERIFY_PARSED_ARGS_PREFIX)
message(FATAL_ERROR "verify_parsed_arguments - Missing required option 'PREFIX'")
endif()
if (NOT DEFINED VERIFY_PARSED_ARGS_FUNCTION_NAME)
message(FATAL_ERROR "verify_parsed_arguments - Missing required option 'FUNCTION_NAME'")
endif()
# Now start the function's actual job: Verifying a top-level function's call to cmake_parse_arguments
if (DEFINED ${VERIFY_PARSED_ARGS_PREFIX}_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "${VERIFY_PARSED_ARGS_FUNCTION_NAME} - Received unrecognized options: ${${VERIFY_PARSED_ARGS_PREFIX}_UNPARSED_ARGUMENTS}")
endif()
if (DEFINED ${VERIFY_PARSED_ARGS_PREFIX}_KEYWORDS_MISSING_VALUES)
message(FATAL_ERROR "${VERIFY_PARSED_ARGS_FUNCTION_NAME} - The following options are missing arguments: ${${VERIFY_PARSED_ARGS_PREFIX}_KEYWORDS_MISSING_VALUES}")
endif()
if (DEFINED VERIFY_PARSED_ARGS_REQUIRED)
foreach(CURRENT_ARG IN LISTS VERIFY_PARSED_ARGS_REQUIRED)
set(CURRENT_ARG "${VERIFY_PARSED_ARGS_PREFIX}_${CURRENT_ARG}")
if (NOT DEFINED ${CURRENT_ARG})
message(FATAL_ERROR "${VERIFY_PARSED_ARGS_FUNCTION_NAME} - Missing required option '${CURRENT_ARG}'")
endif()
endforeach()
endif()
endfunction()
# Initialize variables populated by soci_public_dependency
set(SOCI_DEPENDENCY_VARIABLES
"SOCI_DEPENDENCY_SOCI_COMPONENTS"
"SOCI_DEPENDENCY_NAMES"
"SOCI_DEPENDENCY_TARGETS"
)
if (NOT DEFINED SOCI_UTILS_ALREADY_INCLUDED)
foreach(VAR_NAME IN LISTS SOCI_DEPENDENCY_VARIABLES)
set("${VAR_NAME}" "" CACHE INTERNAL "")
endforeach()
endif()
# This function declares a public dependency of a given target in such a way that
# the dependency is automatically populated to a generated SOCI config file.
#
# Use as
# soci_public_dependency(
# NAME <name>
# DEP_TARGETS <dep target> ...
# TARGET <target>
# )
# where
# - <name> is the name of the dependency (used for lookup via find_package)
# - <dep target> is the name of the target that will be imported upon a
# successful find_package call
# - <target> is the name of the ALIAS target to link the found dependency to
function(soci_public_dependency)
set(ONE_VAL_OPTIONS "TARGET" "NAME")
set(MULTI_VAL_OPTIONS "DEP_TARGETS")
cmake_parse_arguments(PUBLIC_DEP "${FLAGS}" "${ONE_VAL_OPTIONS}" "${MULTI_VAL_OPTIONS}" ${ARGV})
soci_verify_parsed_arguments(
PREFIX "PUBLIC_DEP"
FUNCTION_NAME "soci_public_dependency"
REQUIRED "TARGET" "NAME" "DEP_TARGETS"
)
# Sanity checking
if (NOT TARGET "${PUBLIC_DEP_TARGET}")
message(FATAL_ERROR "Provided TARGET '${PUBLIC_DEP_TARGET}' does not exist")
endif()
get_target_property(UNDERLYING_TARGET "${PUBLIC_DEP_TARGET}" ALIASED_TARGET)
if (NOT UNDERLYING_TARGET)
message(FATAL_ERROR "Provided TARGET '${PUBLIC_DEP_TARGET}' is expected to be an ALIAS target")
endif()
# Bookkeeping
list(APPEND SOCI_DEPENDENCY_SOCI_COMPONENTS "${PUBLIC_DEP_TARGET}")
list(APPEND SOCI_DEPENDENCY_NAMES "${PUBLIC_DEP_NAME}")
list(JOIN PUBLIC_DEP_DEP_TARGETS "|" STORED_TARGETS)
list(APPEND SOCI_DEPENDENCY_TARGETS "${STORED_TARGETS}")
foreach(VAR_NAME IN LISTS SOCI_DEPENDENCY_VARIABLES)
set("${VAR_NAME}" "${${VAR_NAME}}" CACHE INTERNAL "")
endforeach()
# Search for the package now
set(SKIP_SEARCH ON)
foreach (TGT IN LISTS PUBLIC_DEP_DEP_TARGETS)
if (NOT TARGET "${TGT}")
set(SKIP_SEARCH OFF)
endif()
endforeach()
if (NOT SKIP_SEARCH)
find_package("${PUBLIC_DEP_NAME}" REQUIRED)
endif()
set(FOUND_ONE OFF)
foreach (TGT IN LISTS PUBLIC_DEP_DEP_TARGETS)
if (NOT TARGET "${TGT}")
if (FOUND_ONE)
message(DEBUG "The following SOCI dependencies have been found only partially: ${PUBLIC_DEP_DEP_TARGETS}")
endif()
return()
endif()
set(FOUND_ONE ON)
target_link_libraries("${UNDERLYING_TARGET}" PUBLIC "$<BUILD_INTERFACE:${TGT}>")
endforeach()
endfunction()
set(SOCI_UTILS_ALREADY_INCLUDED TRUE)