From 9a1228fc57ea77191fad55bb50683e61de3911db Mon Sep 17 00:00:00 2001 From: Matthias Maier Date: Sun, 27 Nov 2022 05:49:09 -0600 Subject: [PATCH] CMake: add define_interface_target() This function defines interface targets for a given feature described by appropriate CMake variables _. --- cmake/macros/macro_configure_feature.cmake | 1 + .../macro_define_interface_target.cmake | 148 ++++++++++++++++++ cmake/macros/macro_process_feature.cmake | 8 +- 3 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 cmake/macros/macro_define_interface_target.cmake diff --git a/cmake/macros/macro_configure_feature.cmake b/cmake/macros/macro_configure_feature.cmake index ebbf0a7f86..c1080faeb6 100644 --- a/cmake/macros/macro_configure_feature.cmake +++ b/cmake/macros/macro_configure_feature.cmake @@ -248,6 +248,7 @@ macro(configure_feature _feature) if(COMMAND feature_${_feature}_configure_external) evaluate_expression("feature_${_feature}_configure_external()") endif() + define_interface_target(${_feature}) message(STATUS "DEAL_II_WITH_${_feature} successfully set up with external dependencies.") set(FEATURE_${_feature}_EXTERNAL_CONFIGURED TRUE) diff --git a/cmake/macros/macro_define_interface_target.cmake b/cmake/macros/macro_define_interface_target.cmake new file mode 100644 index 0000000000..eca2afe37f --- /dev/null +++ b/cmake/macros/macro_define_interface_target.cmake @@ -0,0 +1,148 @@ +## --------------------------------------------------------------------- +## +## 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( [target_name]) +# +# This function defines interface targets for a given feature described by +# the CMake variables _, 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__debug and +# interface__release. If no *_DEBUG or *_RELEASE variants are +# defined then a single interface_ 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_(|_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_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() diff --git a/cmake/macros/macro_process_feature.cmake b/cmake/macros/macro_process_feature.cmake index b298037c1d..a80d8778da 100644 --- a/cmake/macros/macro_process_feature.cmake +++ b/cmake/macros/macro_process_feature.cmake @@ -47,12 +47,12 @@ # search. # # Valid suffixes are -# CXX_FLAGS CXX_FLAGS_RELEASE CXX_FLAGS_DEBUG -# DEFINITIONS DEFINITIONS_RELEASE DEFINITIONS_DEBUG -# EXECUTABLE -# INCLUDE_DIRS # LIBRARIES LIBRARIES_RELEASE LIBRARIES_DEBUG +# INCLUDE_DIRS +# DEFINITIONS DEFINITIONS_RELEASE DEFINITIONS_DEBUG +# CXX_FLAGS CXX_FLAGS_RELEASE CXX_FLAGS_DEBUG # LINKER_FLAGS LINKER_FLAGS_RELEASE LINKER_FLAGS_DEBUG +# EXECUTABLE # # Note: The contents of all _ variables will be cleared # -- 2.39.5