Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkFunctionUseModules.cmake
Go to the documentation of this file.
2  set(package_list ${ARGN})
3 
4  set(PUBLIC_PACKAGE_NAMES )
5  set(PRIVATE_PACKAGE_NAMES )
6  set(INTERFACE_PACKAGE_NAMES )
7 
8  set(_package_visibility PRIVATE)
9  foreach(_package ${package_list})
10  if(_package STREQUAL "PUBLIC" OR _package STREQUAL "PRIVATE" OR _package STREQUAL "INTERFACE")
11  set(_package_visibility ${_package})
12  else()
13  list(APPEND packages ${_package})
14  set(_package_name )
15  set(_package_components_list )
16  string(REPLACE "|" ";" _package_list ${_package})
17  if("${_package_list}" STREQUAL "${_package}")
18  set(_package_name ${_package})
19  else()
20  list(GET _package_list 0 _package_name)
21  list(GET _package_list 1 _package_components)
22  string(REPLACE "+" ";" _package_components_list "${_package_components}")
23  if(NOT _package_name OR NOT _package_components)
24  message(SEND_ERROR "PACKAGE argument syntax wrong. ${_package} is not of the form PACKAGE[|COMPONENT1[+COMPONENT2]...]")
25  endif()
26  endif()
27  list(APPEND ${_package_visibility}_PACKAGE_NAMES ${_package_name})
28  list(APPEND ${_package_visibility}_${_package_name}_REQUIRED_COMPONENTS ${_package_components_list})
29  endif()
30  endforeach()
31 
32  # remove duplicates and set package components in parent scope
33  foreach(_package_visibility PUBLIC PRIVATE INTERFACE)
34  foreach(_package_name ${${_package_visibility}_PACKAGE_NAMES})
35  if(${_package_visibility}_${_package_name}_REQUIRED_COMPONENTS)
36  list(REMOVE_DUPLICATES ${_package_visibility}_${_package_name}_REQUIRED_COMPONENTS)
37  endif()
38  set(${_package_visibility}_${_package_name}_REQUIRED_COMPONENTS ${${_package_visibility}_${_package_name}_REQUIRED_COMPONENTS} PARENT_SCOPE)
39  endforeach()
40  endforeach()
41 
42  set(PUBLIC_PACKAGE_NAMES ${PUBLIC_PACKAGE_NAMES} PARENT_SCOPE)
43  set(PRIVATE_PACKAGE_NAMES ${PRIVATE_PACKAGE_NAMES} PARENT_SCOPE)
44  set(INTERFACE_PACKAGE_NAMES ${INTERFACE_PACKAGE_NAMES} PARENT_SCOPE)
45  set(PACKAGE_NAMES ${PUBLIC_PACKAGE_NAMES} ${PRIVATE_PACKAGE_NAMES} ${INTERFACE_PACKAGE_NAMES} PARENT_SCOPE)
46 endfunction()
47 
48 function(_include_package_config pkg_config_file)
49  # wrap the inclusion of the MITK_<pkg>_Config.cmake file in a
50  # function to create a scope for its variables; this allows
51  # multiple inclusions of the file in the parent scope
52  include(${pkg_config_file})
53  set(ALL_INCLUDE_DIRECTORIES ${ALL_INCLUDE_DIRECTORIES} PARENT_SCOPE)
54  set(ALL_LIBRARIES ${ALL_LIBRARIES} PARENT_SCOPE)
55  set(ALL_COMPILE_DEFINITIONS ${ALL_COMPILE_DEFINITIONS} PARENT_SCOPE)
56  set(ALL_COMPILE_OPTIONS ${ALL_COMPILE_OPTIONS} PARENT_SCOPE)
57 endfunction()
58 
59 #! This CMake function sets up the necessary include directories,
60 #! linker dependencies, and compile flags for a given target which
61 #! depends on a set of MITK modules or packages.
62 #!
63 #! A package argument is of the form
64 #!
65 #! [PUBLIC|PRIVATE|INTERFACE] PACKAGE[|COMPONENT1[+COMPONENT2]...]
66 #!
67 #! where PACKAGE is the package name (e.g. VTK) and components are
68 #! the names of required package components or libraries.
69 #!
70 #! If a dependency is not available, an error is thrown.
71 function(mitk_use_modules)
72 
73  set(_macro_params
74  TARGET # The target name (required)
75  )
76 
77  set(_macro_multiparams
78  MODULES # MITK modules which the given TARGET uses
79  PACKAGES # MITK packages which the given TARGET uses
80  )
81 
82  set(_macro_options )
83 
84  cmake_parse_arguments(USE "${_macro_options}" "${_macro_params}" "${_macro_multiparams}" ${ARGN})
85 
86  # Sanity checks
87  if(NOT USE_TARGET)
88  message(SEND_ERROR "Required TARGET argument missing.")
89  elseif(NOT TARGET ${USE_TARGET})
90  message(SEND_ERROR "The given TARGET argument ${USE_TARGET} is not a valid target")
91  endif()
92 
93  set(depends ${USE_MODULES})
94  set(package_depends ${USE_PACKAGES})
95 
96  if(depends)
97  # Iterate over all module dependencies
98  foreach(dependency ${depends})
99  if(TARGET ${dependency} AND NOT MODULE_IS_DEPRECATED)
100  get_target_property(_is_interface_lib ${dependency} TYPE)
101  if(NOT _is_interface_lib)
102  get_target_property(_dependency_deprecated_since ${dependency} MITK_MODULE_DEPRECATED_SINCE)
103  if(_dependency_deprecated_since)
104  message(WARNING "Module ${dependency} is deprecated since ${_dependency_deprecated_since}")
105  endif()
106  endif()
107  endif()
108  endforeach()
109  target_link_libraries(${USE_TARGET} PUBLIC ${depends})
110  endif()
111 
112  # Parse package dependencies
113  if(package_depends)
114  _mitk_parse_package_args(${package_depends})
115 
116  # Some package config files like MITK_Qt5_Config.cmake rely on a
117  # properly set "MODULE_NAME" variable for the current target.
118  set(MODULE_NAME ${USE_TARGET})
119  # Read all package information
120  foreach(_package_visibility INTERFACE PUBLIC PRIVATE)
121  foreach(_package ${${_package_visibility}_PACKAGE_NAMES})
122  set(ALL_INCLUDE_DIRECTORIES)
123  set(ALL_LIBRARIES)
124  set(ALL_COMPILE_DEFINITIONS)
125  set(ALL_COMPILE_OPTIONS)
126 
127  set(${_package}_REQUIRED_COMPONENTS_BY_MODULE ${${_package_visibility}_${_package}_REQUIRED_COMPONENTS})
128  set(_package_found 0)
129  foreach(dir ${MODULES_PACKAGE_DEPENDS_DIRS})
130  if((NOT DEFINED MITK_USE_${_package} OR MITK_USE_${_package}) AND EXISTS "${dir}/MITK_${_package}_Config.cmake")
131  _include_package_config("${dir}/MITK_${_package}_Config.cmake")
132  set(_package_found 1)
133  break()
134  endif()
135  endforeach()
136  if(_package_found)
137  if(ALL_INCLUDE_DIRECTORIES)
138  list(REMOVE_DUPLICATES ALL_INCLUDE_DIRECTORIES)
139  target_include_directories(${USE_TARGET} SYSTEM ${_package_visibility} ${ALL_INCLUDE_DIRECTORIES})
140  endif()
141  if(ALL_LIBRARIES)
142  # Don't remove "duplicats" because ALL_LIBRARIES may be of the form:
143  # "general;bla;debug;blad;general;foo;debug;food"
144  target_link_libraries(${USE_TARGET} ${_package_visibility} ${ALL_LIBRARIES})
145  endif()
146  if(ALL_COMPILE_DEFINITIONS)
147  list(REMOVE_DUPLICATES ALL_COMPILE_DEFINITIONS)
148  # Compile definitions are always added "PRIVATE" to avoid multiple definitions
149  # on the command line due to transitive and direct dependencies adding the
150  # same definitions.
151  target_compile_definitions(${USE_TARGET} PRIVATE ${ALL_COMPILE_DEFINITIONS})
152  endif()
153  if(ALL_COMPILE_OPTIONS)
154  list(REMOVE_DUPLICATES ALL_COMPILE_OPTIONS)
155  target_compile_options(${USE_TARGET} ${_package_visibility} ${ALL_COMPILE_OPTIONS})
156  endif()
157  else()
158  message(SEND_ERROR "Missing package: ${_package}")
159  endif()
160  endforeach()
161  endforeach()
162  endif()
163 endfunction()
_mitk_parse_package_args()
const std::string TARGET