--- /dev/null
+## ---------------------------------------------------------------------
+##
+## Copyright (C) 2022 - 2022 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE.md at
+## the top level directory of deal.II.
+##
+## ---------------------------------------------------------------------
+
+#
+# define_interface_target(<feature> [target_name])
+#
+# This function defines interface targets for a given feature described by
+# the CMake variables <FEATURE>_<SUFFIX>, where the suffix is one of the
+# following:
+#
+# LIBRARIES ( LIBRARIES_RELEASE LIBRARIES_DEBUG )
+# TARGETS ( TARGETS_RELEASE TARGETS_DEBUG )
+# - populating the LINK_LIBRARIES target property
+# INCLUDE_DIRS
+# - populating the INCLUDE_DIRECTORIES target property
+# DEFINITIONS ( DEFINITIONS_RELEASE DEFINITIONS_DEBUG )
+# - populating the COMPILE_DEFINITIONS target property
+# CXX_FLAGS ( CXX_FLAGS_RELEASE CXX_FLAGS_DEBUG )
+# - populating the COMPILE_OPTIONS target property
+# LINKER_FLAGS ( LINKER_FLAGS_RELEASE LINKER_FLAGS_DEBUG )
+# - populating the LINK_OPTIONS target property
+#
+# If any *_DEBUG or *_RELEASE variable is populated then this macro defines
+# two targets named interface_<feature>_debug and
+# interface_<feature>_release. If no *_DEBUG or *_RELEASE variants are
+# defined then a single interface_<feature> target is defined.
+#
+# - All interface targets are added automatically to
+# ${DEAL_II_PROJECT_CONFIG_NAME}Targets.cmake
+# for build and install locations.
+#
+# - The function also adds all targets to DEAL_II_TARGETS (for non
+# debug/release split) and DEAL_II_TARGETS_(DEBUG|RELEASE) (for split
+# targets), respectively.
+#
+# The default name, i.e., interface_<feature>(|_debug|_release) can be
+# overriden by the optional second argument. For example,
+# define_interface_target(DEAL_II base_configuration)
+# will define interface_base_configuration* targets but query all
+# information from DEAL_II_* variables.
+#
+
+function(define_interface_target _feature)
+ string(TOLOWER "${_feature}" _feature_lowercase)
+ if(NOT "${ARGN}" STREQUAL "")
+ set(_feature_lowercase "${ARGN}")
+ endif()
+
+ set(_builds "dummy")
+ if(${_feature}_SPLIT_CONFIGURATION)
+ set(_builds ${DEAL_II_BUILD_TYPES})
+ endif()
+
+ foreach(_build ${_builds})
+ set(_interface_target "interface_${_feature_lowercase}")
+
+ if(${_feature}_SPLIT_CONFIGURATION)
+ string(TOLOWER "${_build}" _build_lowercase)
+ string(APPEND _interface_target "_${_build_lowercase}")
+ endif()
+
+ message(STATUS "")
+ message(STATUS "Defining target: ${_interface_target}")
+
+ add_library(${_interface_target} INTERFACE)
+
+ if(DEFINED ${_feature}_VERSION)
+ message(STATUS " VERSION: ${${_feature}_VERSION}")
+ set_target_properties(${_interface_target}
+ PROPERTIES VERSION "${${_feature_}_VERSION}"
+ )
+ endif()
+
+ set(_libraries)
+ list(APPEND _libraries
+ ${${_feature}_LIBRARIES} ${${_feature}_LIBRARIES_${_build}}
+ ${${_feature}_TARGETS} ${${_feature}_TARGETS_${_build}}
+ )
+ if(NOT "${_libraries}" STREQUAL "")
+ message(STATUS " LINK_LIBRARIES: ${_libraries}")
+ target_link_libraries(${_interface_target} INTERFACE ${_libraries})
+ endif()
+
+ if(DEFINED ${_feature}_INCLUDE_DIRS)
+ message(STATUS " INCLUDE_DIRECTORIES: ${${_feature}_INCLUDE_DIRS}")
+ target_include_directories(${_interface_target}
+ SYSTEM INTERFACE ${${_feature}_INCLUDE_DIRS}
+ )
+ endif()
+
+ set(_definitions)
+ list(APPEND _definitions ${${_feature}_DEFINITIONS} ${${_feature}_DEFINITIONS_${_build}})
+ if(NOT "${_definitions}" STREQUAL "")
+ message(STATUS " COMPILE_DEFINITIONS: ${_definitions}")
+ target_compile_definitions(${_interface_target} INTERFACE ${_definitions})
+ endif()
+
+ separate_arguments(_compile_options UNIX_COMMAND
+ "${${_feature}_CXX_FLAGS} ${${_feature}_CXX_FLAGS_${_build}}"
+ )
+ if(NOT "${_compile_options}" STREQUAL "")
+ message(STATUS " COMPILE_OPTIONS: ${_compile_options}")
+ target_compile_options(${_interface_target} INTERFACE $<$<COMPILE_LANGUAGE:CXX>:${_compile_options}>)
+ endif()
+
+ separate_arguments(_link_options UNIX_COMMAND
+ "${${_feature}_LINKER_FLAGS} ${${_feature}_LINKER_FLAGS_${_build}}"
+ )
+ if(NOT "${_link_options}" STREQUAL "")
+ message(STATUS " LINK_OPTIONS: ${_link_options}")
+ target_link_options(${_interface_target} INTERFACE ${_link_options})
+ endif()
+
+ export(TARGETS ${_interface_target}
+ NAMESPACE "${DEAL_II_NAMESPACE}::"
+ FILE ${CMAKE_BINARY_DIR}/${DEAL_II_PROJECT_CONFIG_RELDIR}/${DEAL_II_PROJECT_CONFIG_NAME}Targets.cmake
+ APPEND
+ )
+
+ install(TARGETS ${_interface_target}
+ COMPONENT library
+ EXPORT ${DEAL_II_PROJECT_CONFIG_NAME}Targets
+ )
+
+ if(${_feature}_SPLIT_CONFIGURATION)
+ # Future FIXME: change to block(PARENT_SCOPE)/endblock() (CMake 3.25)
+ list(APPEND DEAL_II_TARGETS_${_build} "${_interface_target}")
+ set(DEAL_II_TARGETS_${_build} ${DEAL_II_TARGETS_${_build}} PARENT_SCOPE)
+ else()
+ # Future FIXME: change to block(PARENT_SCOPE)/endblock() (CMake 3.25)
+ list(APPEND DEAL_II_TARGETS "${_interface_target}")
+ set(DEAL_II_TARGETS ${DEAL_II_TARGETS} PARENT_SCOPE)
+ endif()
+
+ endforeach()
+endfunction()