CTK  0.1.0
The Common Toolkit is a community effort to provide support code for medical image analysis, surgical navigation, and related projects.
ctkMacroSetupPlugins.cmake
Go to the documentation of this file.
1 ###########################################################################
2 #
3 # Library: CTK
4 #
5 # Copyright (c) German Cancer Research Center,
6 # Division of Medical and Biological Informatics
7 #
8 # Licensed under the Apache License, Version 2.0 (the "License");
9 # you may not use this file except in compliance with the License.
10 # You may obtain a copy of the License at
11 #
12 # http://www.apache.org/licenses/LICENSE-2.0
13 #
14 # Unless required by applicable law or agreed to in writing, software
15 # distributed under the License is distributed on an "AS IS" BASIS,
16 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 # See the License for the specific language governing permissions and
18 # limitations under the License.
19 #
20 ###########################################################################
21 
22 macro(ctkMacroSetupExternalPlugins )
23  message(SEND_ERROR "This macro has been renamed. Please use ctkMacroSetupPlugins instead")
24 endmacro()
25 
26 #! This is the main macro to set up your CTK plug-ins inside your own CMake project.
27 #!
28 #! This macro takes care of validating the current set of plug-in build options,
29 #! enables and/or checks required plug-ins and handles all aspects of plug-in
30 #! dependencies. Additionally, it calls add_subdirectory() on each given plug-in.
31 #!
32 #! Macro signature:
33 #! \code
34 #! ctkMacroSetupPlugins(plugins...
35 #! [BUILD_OPTION_PREFIX <option_prefix>]
36 #! [APPS <apps...>]
37 #! [BUILD_ALL <build_all_flag>]
38 #! [COMPACT_OPTIONS])
39 #! \endcode
40 #!
41 #! \param plugins (required) A list of directories (absolute or relative to the current
42 #! source dir) with default build options. E.g. an item of the list may look like
43 #! "Plugins/org.myproject.example:ON"
44 #! \param BUILD_OPTION_PREFIX (optional) The prefix to use for the build option of th
45 #! plug-in. Defaults to "BUILD_".
46 #! \param APPS (optional) A list of directories with build option names containing
47 #! CTK-style applications. This can be used to automatically enable plug-ins
48 #! required by the application. The application directoy must contain a CMakeLists.txt
49 #! file containing a "project(...)" command and a target_libraries.cmake file
50 #! containing a list of required plug-in targets, e.g. "set(target_libraries org_myproject_example)".
51 #! An item of the list may look like "Apps/MyExampleApp^^BUILD_APP_MyExampleApp" where
52 #! Apps/MyExampleApp is the directory containing the applicatios CMakeLists.txt file
53 #! and BUILD_APP_MyExampleApp is the build option used to conditionally build the app.
54 #! \param BUILD_ALL (optional) If the build_all_flag is true, all entries in the plugins list
55 #! will be enabled (but their build option will not be forced to change). Default is OFF
56 #! \param COMPACT_OPTIONS (optional) If this flag is given, the created build options for the
57 #! plugins will not contain the relative path but just the last directory entry which
58 #! usually is the plug-in symbolic name.
59 #!
60 #! Example invocation:
61 #!
62 #! \code
63 #! set(plugin_list Plugins/org.myproject.example:OFF)
64 #! set(app_list Apps/MyExampleApp^^MYPROJECT_BUILD_MyExampleApp)
65 #!
66 #! ctkMacroSetupPlugins(${plugin_list}
67 #! BUILD_OPTION_PREFIX MYPROJECT_BUILD_
68 #! APPS ${app_list}
69 #! COMPACT_OPTIONS
70 #! )
71 #! \endcode
72 #!
73 #! \ingroup CMakeAPI
74 macro(ctkMacroSetupPlugins )
75 
76  ctkMacroParseArguments(MY "BUILD_OPTION_PREFIX;APPS;BUILD_ALL" "COMPACT_OPTIONS" ${ARGN})
77 
78  if(NOT MY_DEFAULT_ARGS)
79  message(FATAL_ERROR "Empty plugin list")
80  endif()
81 
82  set(plugin_list ${MY_DEFAULT_ARGS})
83 
84  if(NOT MY_BUILD_OPTION_PREFIX)
85  set(MY_BUILD_OPTION_PREFIX "BUILD_")
86  endif()
87 
88  if(NOT MY_BUILD_ALL)
89  set(MY_BUILD_ALL 0)
90  endif()
91 
92  # Check if this is the first invocation of this macro
93  get_property(_repeated GLOBAL PROPERTY ctkMacroSetupExternalPlugins_called SET)
94  if(NOT _repeated)
95  # Clear the internal cache variable containing all enabled plug-in targets
96  # This variable will be set in ctkMacroBuildPlugin
97  set(${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES CACHE INTERNAL "CTK plug-in targets" FORCE)
98  set_property(GLOBAL PROPERTY ctkMacroSetupExternalPlugins_called 1)
99 
100  # Add the project specific variable name containing plug-in targets to the list
101  set_property(GLOBAL APPEND PROPERTY CTK_PLUGIN_LIBRARIES_VARS ${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES)
102  endif()
103 
104  # Set up Qt, if not already done
105  #if(NOT QT4_FOUND)
106  # set(minimum_required_qt_version "4.6")
107  # find_package(Qt4 REQUIRED)
108 
109  # if("${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}" VERSION_LESS "${minimum_required_qt_version}")
110  # message(FATAL_ERROR "error: CTK requires Qt >= ${minimum_required_qt_version} -- you cannot use Qt ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}.")
111  # endif()
112  #endif()
113 
114  # Set the variable QT_INSTALLED_LIBRARY_DIR that contains all
115  # Qt shared libraries
116  if (CTK_QT_VERSION VERSION_GREATER "4")
117  if(WIN32)
118  get_target_property(_qt5_moc_executable Qt5::moc LOCATION)
119  get_filename_component(QT_INSTALLED_LIBRARY_DIR ${_qt5_moc_executable} PATH)
120  else()
121  get_target_property(_qt5_core_lib Qt5::Core LOCATION)
122  get_filename_component(QT_INSTALLED_LIBRARY_DIR ${_qt5_core_lib} PATH)
123  endif()
124  else()
125  set(QT_INSTALLED_LIBRARY_DIR ${QT_LIBRARY_DIR})
126  if(WIN32)
127  get_filename_component(QT_INSTALLED_LIBRARY_DIR ${QT_QMAKE_EXECUTABLE} PATH)
128  endif()
129  endif()
130 
131  set(plugin_symbolic_names )
132  set(plugin_targets )
133  foreach(plugin ${plugin_list})
134  ctkFunctionExtractOptionNameAndValue(${plugin} plugin_dir plugin_value)
135  string(REPLACE "/" ";" _tokens ${plugin_dir})
136  list(GET _tokens -1 plugin_symbolic_name)
137  list(APPEND plugin_symbolic_names ${plugin_symbolic_name})
138 
139  string(REPLACE "." "_" plugin_target ${plugin_symbolic_name})
140  list(APPEND plugin_targets ${plugin_target})
141 
142  set(${plugin_symbolic_name}_plugin_dir ${plugin_dir})
143  set(${plugin_symbolic_name}_plugin_value ${plugin_value})
144  endforeach()
145 
146  # Check if the plugin symbolic names are valid for the current project
147  ctkMacroGetAllNonProjectTargetLibraries("${plugin_targets}" invalid_targets)
148  if(invalid_targets)
149  set(invalid_plugins )
150  foreach(plugin_target ${invalid_targets})
151  string(REPLACE "_" "." plugin_symbolic_name ${plugin_target})
152  list(APPEND invalid_plugins ${plugin_symbolic_name})
153  endforeach()
154  message(FATAL_ERROR "The following plug-ins are using invalid symbolic names: ${invalid_plugins}")
155  endif()
156 
157  set(plugin_dirswithoption )
158  set(plugin_subdirs )
159  foreach(plugin_symbolic_name ${plugin_symbolic_names})
160  if(MY_COMPACT_OPTIONS)
161  set(option_name ${MY_BUILD_OPTION_PREFIX}${plugin_symbolic_name})
162  else()
163  set(option_name ${MY_BUILD_OPTION_PREFIX}${${plugin_symbolic_name}_plugin_dir})
164  endif()
165  # This variable may have the form "Plugins/org.commontk.bla_option_name"
166  set(${${plugin_symbolic_name}_plugin_dir}_option_name ${option_name})
167  # Additionally create a variable of the form "org_commontk_bla_option_name"
168  string(REPLACE "." "_" plugin_target ${plugin_symbolic_name})
169  set(${plugin_target}_option_name ${option_name})
170 
171  option(${option_name} "Build the ${plugin_symbolic_name} Plugin." ${${plugin_symbolic_name}_plugin_value})
172  if(MY_BUILD_ALL)
173  set(${option_name} 1)
174  endif()
175 
176  list(APPEND plugin_subdirs "${${plugin_symbolic_name}_plugin_dir}")
177  if(IS_ABSOLUTE ${${plugin_symbolic_name}_plugin_dir})
178  list(APPEND plugin_dirswithoption "${${plugin_symbolic_name}_plugin_dir}^^${option_name}")
179  else()
180  list(APPEND plugin_dirswithoption "${CMAKE_CURRENT_SOURCE_DIR}/${${plugin_symbolic_name}_plugin_dir}^^${option_name}")
181  endif()
182  endforeach()
183 
184  # Get plugin info from possible previous invocations of this macro for
185  # validation purposes below
186  get_property(previous_plugin_dirswithoption GLOBAL PROPERTY ctkMacroSetupExternalPlugins_dirswithoption)
187 
188  # Fill the CTK_EXTERNAL_PLUGIN_LIBRARIES variable with external plug-in target names.
189  # It will be used in ctkMacroValidateBuildOptions to be able to validate agains plug-ins
190  # from external projects.
191  ctkFunctionGetAllPluginTargets(CTK_EXTERNAL_PLUGIN_LIBRARIES)
192 
193  ctkFunctionGenerateDGraphInput(${CMAKE_CURRENT_BINARY_DIR}
194  "${plugin_dirswithoption};${previous_plugin_dirswithoption};${MY_APPS}"
195  WITH_EXTERNALS)
196  ctkMacroValidateBuildOptions("${CMAKE_CURRENT_BINARY_DIR}" "${CTK_DGRAPH_EXECUTABLE}"
197  "${MY_APPS};${plugin_dirswithoption};${previous_plugin_dirswithoption}")
198 
199  # Record the current set of plug-ins and their option names
200  set_property(GLOBAL APPEND PROPERTY ctkMacroSetupExternalPlugins_dirswithoption ${plugin_dirswithoption})
201 
202  # Get the gcc version (GCC_VERSION will be empty if the compiler is not gcc).
203  # This will be used in the ctkMacroBuildPlugin macro to conditionally set compiler flags.
204  ctkFunctionGetGccversion(${CMAKE_CXX_COMPILER} GCC_VERSION)
205 
206  foreach(plugin ${plugin_subdirs})
207  if(${${plugin}_option_name})
208  if(IS_ABSOLUTE ${plugin})
209  # get last directory component
210  get_filename_component(_dirname ${plugin} NAME)
211  add_subdirectory(${plugin} private_plugins/${_dirname})
212  else()
213  add_subdirectory(${plugin})
214  endif()
215  endif()
216  endforeach()
217 
218 endmacro()