From 6a3cc54d73f9f59562bee6749813bd32465960c5 Mon Sep 17 00:00:00 2001 From: Matthias Maier Date: Mon, 22 May 2023 11:25:28 -0500 Subject: [PATCH] CMake: introduce copy_target_properties() macro This macro is used to copy target properties from imported targets recursively into our interface targets. This will allow us to modernize our configure_ macros to use imported targets directly instead of extracting all of this information for each external feature. --- .../macros/macro_copy_target_properties.cmake | 140 ++++++++++++++++++ .../macro_define_interface_target.cmake | 7 +- 2 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 cmake/macros/macro_copy_target_properties.cmake diff --git a/cmake/macros/macro_copy_target_properties.cmake b/cmake/macros/macro_copy_target_properties.cmake new file mode 100644 index 0000000000..4834bf087f --- /dev/null +++ b/cmake/macros/macro_copy_target_properties.cmake @@ -0,0 +1,140 @@ +## --------------------------------------------------------------------- +## +## 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. +## +## --------------------------------------------------------------------- + +# +# copy_target_properties( []) +# +# Copies relevant (imported) target properties from the source targets and +# appends the properties to the destination target. +# + +function(copy_target_properties _destination_target) + + # + # Make sure that we expand all targets recursively for the sake of a + # cleaner output we check whether we have already included a given target + # + + set(_source_targets ${ARGN}) + set(_processed_targets) + + # + # Collect values over all targets found in ${_source_targets}: + # + + set(_libraries) + set(_include_directories) + set(_compile_definitions) + set(_compile_options) + set(_link_options) + + while(NOT "${_source_targets}" STREQUAL "") + # Future FIXME: replace by POP_FRONT (CMake 3.15) + list(GET _source_targets 0 _entry) + list(REMOVE_AT _source_targets 0) + + if(${_entry} IN_LIST _processed_targets) + continue() + endif() + + list(APPEND _processed_targets ${_entry}) + message(STATUS " copying ${_entry} into ${_destination_target} ...") + + get_target_property(_location ${_entry} IMPORTED_LOCATION) + if("${_location}" MATCHES "-NOTFOUND") + set(_location) + endif() + + get_target_property(_values ${_entry} INTERFACE_LINK_LIBRARIES) + if("${_values}" MATCHES "-NOTFOUND") + set(_values) + endif() + + foreach(_lib ${_location} ${_values}) + if(TARGET ${_lib}) + list(APPEND _source_targets ${_lib}) + else() + # Warn loudly if we encounter an undefined target: + if("${_lib}" MATCHES "::") + message(WARNING + "Undefined imported target name »${_lib}« present in interface " + "of target »${_entry}«" + ) + endif() + list(APPEND _libraries ${_entry}) + endif() + endforeach() + + get_target_property(_values ${_entry} INTERFACE_INCLUDE_DIRECTORIES) + if(NOT "${_values}" MATCHES "-NOTFOUND") + list(APPEND _include_directories ${_values}) + endif() + + get_target_property(_values ${_entry} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if(NOT "${_values}" MATCHES "-NOTFOUND") + list(APPEND _include_directories ${_values}) + endif() + + get_target_property(_values ${_entry} INTERFACE_COMPILE_DEFINITIONS) + if(NOT "${_values}" MATCHES "-NOTFOUND") + list(APPEND _compile_definitions ${_values}) + endif() + + get_target_property(_values ${_entry} INTERFACE_COMPILE_OPTIONS) + if(NOT "${_values}" MATCHES "-NOTFOUND") + list(APPEND _compile_options ${_values}) + endif() + + get_target_property(_values ${_entry} INTERFACE_LINK_OPTIONS) + if(NOT "${_values}" MATCHES "-NOTFOUND") + list(APPEND _link_options ${_values}) + endif() + endwhile() + + # + # Populate destination target: + # + + if(NOT "${_libraries}" STREQUAL "") + remove_duplicates(_libraries REVERSE) + message(STATUS " LINK_LIBRARIES: ${_libraries}") + target_link_libraries(${_destination_target} INTERFACE ${_libraries}) + endif() + + if(NOT "${_include_directories}" STREQUAL "") + remove_duplicates(_include_directories) + message(STATUS " INCLUDE_DIRECTORIES: ${_include_directories}") + target_include_directories(${_destination_target} SYSTEM INTERFACE ${_include_directories}) + endif() + + if(NOT "${_compile_definitions}" STREQUAL "") + remove_duplicates(_compile_definitions REVERSE) + message(STATUS " COMPILE_DEFINITIONS: ${_compile_definitions}") + target_compile_definitions(${_destination_target} INTERFACE ${_compile_definitions}) + endif() + + if(NOT "${_compile_options}" STREQUAL "") + remove_duplicates(_compile_options REVERSE) + message(STATUS " COMPILE_OPTIONS: ${_compile_options}") + target_compile_options(${_destination_target} INTERFACE ${_compile_options}) + endif() + + if(NOT "${_link_options}" STREQUAL "") + remove_duplicates(_link_options REVERSE) + message(STATUS " LINK_OPTIONS: ${_link_options}") + target_compile_options(${_destination_target} INTERFACE ${_link_options}) + endif() +endfunction() + diff --git a/cmake/macros/macro_define_interface_target.cmake b/cmake/macros/macro_define_interface_target.cmake index 85ff8da600..afa17aabc3 100644 --- a/cmake/macros/macro_define_interface_target.cmake +++ b/cmake/macros/macro_define_interface_target.cmake @@ -90,7 +90,6 @@ function(define_interface_target _feature) set(_libraries) list(APPEND _libraries ${${_feature}_LIBRARIES} ${${_feature}_LIBRARIES_${_build}} - ${${_feature}_TARGETS} ${${_feature}_TARGETS_${_build}} ) if(NOT "${_libraries}" STREQUAL "") message(STATUS " LINK_LIBRARIES: ${_libraries}") @@ -129,6 +128,12 @@ function(define_interface_target _feature) target_link_options(${_interface_target} INTERFACE ${_link_options}) endif() + if(NOT "${${_feature}_TARGETS}${${_feature}_TARGETS_${_build}}" STREQUAL "") + set(_targets ${${_feature}_TARGETS}${${_feature}_TARGETS_${_build}}) + message(STATUS " IMPORTED TARGETS: ${_targets}") + copy_target_properties(${_interface_target} ${${_feature}_TARGETS} ${${_feature}_TARGETS_${_build}}) + endif() + export(TARGETS ${_interface_target} NAMESPACE "${DEAL_II_TARGET_NAME}::" FILE ${CMAKE_BINARY_DIR}/${DEAL_II_PROJECT_CONFIG_RELDIR}/${DEAL_II_PROJECT_CONFIG_NAME}Targets.cmake -- 2.39.5