diff --git a/CMake/mitkFunctionUseModules.cmake b/CMake/mitkFunctionUseModules.cmake index 173e0a5a95..c1bec4eae5 100644 --- a/CMake/mitkFunctionUseModules.cmake +++ b/CMake/mitkFunctionUseModules.cmake @@ -1,163 +1,169 @@ function(_mitk_parse_package_args) set(package_list ${ARGN}) set(PUBLIC_PACKAGE_NAMES ) set(PRIVATE_PACKAGE_NAMES ) set(INTERFACE_PACKAGE_NAMES ) set(_package_visibility PRIVATE) foreach(_package ${package_list}) if(_package STREQUAL "PUBLIC" OR _package STREQUAL "PRIVATE" OR _package STREQUAL "INTERFACE") set(_package_visibility ${_package}) else() list(APPEND packages ${_package}) set(_package_name ) set(_package_components_list ) string(REPLACE "|" ";" _package_list ${_package}) if("${_package_list}" STREQUAL "${_package}") set(_package_name ${_package}) else() list(GET _package_list 0 _package_name) list(GET _package_list 1 _package_components) string(REPLACE "+" ";" _package_components_list "${_package_components}") if(NOT _package_name OR NOT _package_components) message(SEND_ERROR "PACKAGE argument syntax wrong. ${_package} is not of the form PACKAGE[|COMPONENT1[+COMPONENT2]...]") endif() endif() list(APPEND ${_package_visibility}_PACKAGE_NAMES ${_package_name}) list(APPEND ${_package_visibility}_${_package_name}_REQUIRED_COMPONENTS ${_package_components_list}) endif() endforeach() # remove duplicates and set package components in parent scope foreach(_package_visibility PUBLIC PRIVATE INTERFACE) foreach(_package_name ${${_package_visibility}_PACKAGE_NAMES}) if(${_package_visibility}_${_package_name}_REQUIRED_COMPONENTS) list(REMOVE_DUPLICATES ${_package_visibility}_${_package_name}_REQUIRED_COMPONENTS) endif() set(${_package_visibility}_${_package_name}_REQUIRED_COMPONENTS ${${_package_visibility}_${_package_name}_REQUIRED_COMPONENTS} PARENT_SCOPE) endforeach() endforeach() set(PUBLIC_PACKAGE_NAMES ${PUBLIC_PACKAGE_NAMES} PARENT_SCOPE) set(PRIVATE_PACKAGE_NAMES ${PRIVATE_PACKAGE_NAMES} PARENT_SCOPE) set(INTERFACE_PACKAGE_NAMES ${INTERFACE_PACKAGE_NAMES} PARENT_SCOPE) set(PACKAGE_NAMES ${PUBLIC_PACKAGE_NAMES} ${PRIVATE_PACKAGE_NAMES} ${INTERFACE_PACKAGE_NAMES} PARENT_SCOPE) endfunction() function(_include_package_config pkg_config_file) # wrap the inclusion of the MITK__Config.cmake file in a # function to create a scope for its variables; this allows # multiple inclusions of the file in the parent scope include(${pkg_config_file}) set(ALL_INCLUDE_DIRECTORIES ${ALL_INCLUDE_DIRECTORIES} PARENT_SCOPE) + set(ALL_LINK_DIRECTORIES ${ALL_LINK_DIRECTORIES} PARENT_SCOPE) set(ALL_LIBRARIES ${ALL_LIBRARIES} PARENT_SCOPE) set(ALL_COMPILE_DEFINITIONS ${ALL_COMPILE_DEFINITIONS} PARENT_SCOPE) set(ALL_COMPILE_OPTIONS ${ALL_COMPILE_OPTIONS} PARENT_SCOPE) endfunction() #! This CMake function sets up the necessary include directories, #! linker dependencies, and compile flags for a given target which #! depends on a set of MITK modules or packages. #! #! A package argument is of the form #! #! [PUBLIC|PRIVATE|INTERFACE] PACKAGE[|COMPONENT1[+COMPONENT2]...] #! #! where PACKAGE is the package name (e.g. VTK) and components are #! the names of required package components or libraries. #! #! If a dependency is not available, an error is thrown. function(mitk_use_modules) set(_macro_params TARGET # The target name (required) ) set(_macro_multiparams MODULES # MITK modules which the given TARGET uses PACKAGES # MITK packages which the given TARGET uses ) set(_macro_options ) cmake_parse_arguments(USE "${_macro_options}" "${_macro_params}" "${_macro_multiparams}" ${ARGN}) # Sanity checks if(NOT USE_TARGET) message(SEND_ERROR "Required TARGET argument missing.") elseif(NOT TARGET ${USE_TARGET}) message(SEND_ERROR "The given TARGET argument ${USE_TARGET} is not a valid target") endif() set(depends ${USE_MODULES}) set(package_depends ${USE_PACKAGES}) if(depends) # Iterate over all module dependencies foreach(dependency ${depends}) if(TARGET ${dependency} AND NOT MODULE_IS_DEPRECATED) get_target_property(_is_interface_lib ${dependency} TYPE) if(NOT _is_interface_lib) get_target_property(_dependency_deprecated_since ${dependency} MITK_MODULE_DEPRECATED_SINCE) if(_dependency_deprecated_since) message(WARNING "Module ${dependency} is deprecated since ${_dependency_deprecated_since}") endif() endif() endif() endforeach() target_link_libraries(${USE_TARGET} PUBLIC ${depends}) endif() # Parse package dependencies if(package_depends) _mitk_parse_package_args(${package_depends}) # Some package config files like MITK_Qt5_Config.cmake rely on a # properly set "MODULE_NAME" variable for the current target. set(MODULE_NAME ${USE_TARGET}) # Read all package information foreach(_package_visibility INTERFACE PUBLIC PRIVATE) foreach(_package ${${_package_visibility}_PACKAGE_NAMES}) set(ALL_INCLUDE_DIRECTORIES) + set(ALL_LINK_DIRECTORIES) set(ALL_LIBRARIES) set(ALL_COMPILE_DEFINITIONS) set(ALL_COMPILE_OPTIONS) set(${_package}_REQUIRED_COMPONENTS_BY_MODULE ${${_package_visibility}_${_package}_REQUIRED_COMPONENTS}) set(_package_found 0) foreach(dir ${MODULES_PACKAGE_DEPENDS_DIRS}) if((NOT DEFINED MITK_USE_${_package} OR MITK_USE_${_package}) AND EXISTS "${dir}/MITK_${_package}_Config.cmake") _include_package_config("${dir}/MITK_${_package}_Config.cmake") set(_package_found 1) break() endif() endforeach() if(_package_found) if(ALL_INCLUDE_DIRECTORIES) list(REMOVE_DUPLICATES ALL_INCLUDE_DIRECTORIES) target_include_directories(${USE_TARGET} SYSTEM ${_package_visibility} ${ALL_INCLUDE_DIRECTORIES}) endif() + if(ALL_LINK_DIRECTORIES) + list(REMOVE_DUPLICATES ALL_LINK_DIRECTORIES) + target_link_directories(${USE_TARGET} ${_package_visibility} ${ALL_LINK_DIRECTORIES}) + endif() if(ALL_LIBRARIES) # Don't remove "duplicats" because ALL_LIBRARIES may be of the form: # "general;bla;debug;blad;general;foo;debug;food" target_link_libraries(${USE_TARGET} ${_package_visibility} ${ALL_LIBRARIES}) endif() if(ALL_COMPILE_DEFINITIONS) list(REMOVE_DUPLICATES ALL_COMPILE_DEFINITIONS) # Compile definitions are always added "PRIVATE" to avoid multiple definitions # on the command line due to transitive and direct dependencies adding the # same definitions. target_compile_definitions(${USE_TARGET} PRIVATE ${ALL_COMPILE_DEFINITIONS}) endif() if(ALL_COMPILE_OPTIONS) list(REMOVE_DUPLICATES ALL_COMPILE_OPTIONS) target_compile_options(${USE_TARGET} ${_package_visibility} ${ALL_COMPILE_OPTIONS}) endif() else() message(SEND_ERROR "Missing package: ${_package}") endif() endforeach() endforeach() endif() endfunction()