CTK  0.1.0
The Common Toolkit is a community effort to provide support code for medical image analysis, surgical navigation, and related projects.
ctkMacroValidateBuildOptions.cmake
Go to the documentation of this file.
1 ###########################################################################
2 #
3 # Library: CTK
4 #
5 # Copyright (c) Kitware Inc.
6 #
7 # Licensed under the Apache License, Version 2.0 (the "License");
8 # you may not use this file except in compliance with the License.
9 # You may obtain a copy of the License at
10 #
11 # http://www.apache.org/licenses/LICENSE-2.0.txt
12 #
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
18 #
19 ###########################################################################
20 
21 #! \ingroup CMakeUtilities
22 macro(ctkMacroGetOptionName target_directories_with_target_name target_name option_name_var)
23 
24  foreach(target_info ${target_directories_with_target_name})
25  # extract target_dir and option_name
26  #message("target_info:${target_info}")
27  string(REPLACE "^^" "\\;" target_info_list ${target_info})
28  set(target_info_list ${target_info_list})
29  list(GET target_info_list 0 _target_dir)
30  list(GET target_info_list 1 _option_name)
31  list(GET target_info_list 2 _target_name)
32  if(${_target_name} STREQUAL ${target_name})
33  set(${option_name_var} ${_option_name})
34  endif()
35  endforeach()
36 endmacro()
37 
38 #! \ingroup CMakeUtilities
39 macro(ctkMacroValidateBuildOptions dir executable target_directories)
40  if(NOT EXISTS ${dir})
41  message(FATAL_ERROR "Directory ${dir} doesn't exist!")
42  endif()
43 
44  if(NOT EXISTS ${executable})
45  message(FATAL_ERROR "Executable ${executable} doesn't exist!")
46  endif()
47 
48  set(known_targets)
49  set(target_directories_with_target_name)
50 
51  # Create target_directories_with_target_name
52  foreach(target_info ${target_directories})
53 
54  # extract target_dir and option_name
55  string(REPLACE "^^" "\\;" target_info ${target_info})
56  set(target_info_list ${target_info})
57  list(GET target_info_list 0 target_dir)
58  list(GET target_info_list 1 option_name)
59  #message(STATUS target_dir:${target_dir})
60  #message(STATUS option_name:${option_name})
61  #message(STATUS option_name-value:${${option_name}})
62 
63  # make sure the directory exists
64  if(NOT EXISTS ${target_dir}/CMakeLists.txt)
65  message(FATAL_ERROR "Target directory ${target_dir}/CMakeLists.txt doesn't exists !")
66  endif()
67 
68  # extract project name from CMakeLists.txt
69  file(STRINGS "${target_dir}/CMakeLists.txt" project_string
70  REGEX "^ *(P|p)(R|r)(O|o)(J|j)(E|e)(C|c)(T|t)\\‍("
71  LIMIT_COUNT 10)
72  string(REGEX MATCH "\\‍((.*)\\‍)" target_project_name ${project_string})
73  string(REGEX REPLACE "\\‍(|\\‍)" "" target_project_name ${target_project_name})
74  if(${target_project_name} STREQUAL "")
75  message(FATAL_ERROR "Failed to extract project name from ${target_dir}/CMakeLists.txt")
76  endif()
77  #message(STATUS target_project_name:${target_project_name})
78 
79  list(APPEND target_directories_with_target_name
80  ${target_dir}^^${option_name}^^${target_project_name}
81  )
82 
83  list(APPEND known_targets ${target_project_name})
84  endforeach()
85 
86  # This is for external projects using CTK
87  # The variable CTK_EXTERNAL_PLUGIN_LIBRARIES is filled in ctkMacroSetupExternalPlugins
88  # with the help of variables defined in "PluginUseFiles" from external projects.
89  if(CTK_EXTERNAL_PLUGIN_LIBRARIES)
90  list(APPEND known_targets ${CTK_EXTERNAL_PLUGIN_LIBRARIES})
91  endif()
92  # The variable CTK_LIBRARIES is set in CTKConfig.cmake
93  if(CTK_LIBRARIES)
94  list(APPEND known_targets ${CTK_LIBRARIES})
95  endif()
96 
97  #message("Known targets: ${known_targets}")
98 
99  set(EXTERNAL_TARGETS ) # This is used in CMakeLists.txt
100  foreach(target_info ${target_directories_with_target_name})
101 
102  # extract target_dir and option_name
103  string(REPLACE "^^" "\\;" target_info ${target_info})
104  set(target_info_list ${target_info})
105  list(GET target_info_list 0 target_dir)
106  list(GET target_info_list 1 option_name)
107  #message(STATUS target_dir:${target_dir})
108  #message(STATUS option_name:${option_name})
109  #message(STATUS option_name-value:${${option_name}})
110 
111  # make sure the directory exists
112  if(NOT EXISTS ${target_dir}/CMakeLists.txt)
113  message(FATAL_ERROR "Target directory ${target_dir}/CMakeLists.txt doesn't exists !")
114  endif()
115 
116  # extract project name from CMakeLists.txt
117  file(STRINGS "${target_dir}/CMakeLists.txt" project_string
118  REGEX "^ *(P|p)(R|r)(O|o)(J|j)(E|e)(C|c)(T|t)\\‍("
119  LIMIT_COUNT 10)
120  string(REGEX MATCH "\\‍((.*)\\‍)" target_project_name ${project_string})
121  string(REGEX REPLACE "\\‍(|\\‍)" "" target_project_name ${target_project_name})
122  if(${target_project_name} STREQUAL "")
123  message(FATAL_ERROR "Failed to extract project name from ${target_dir}/CMakeLists.txt")
124  endif()
125  #message(STATUS target_project_name:${target_project_name})
126 
127  # Obtain dependency path
128  ctkMacroSetPaths("${QT_INSTALLED_LIBRARY_DIR}")
129  execute_process(
130  COMMAND "${executable}" "${dir}/DGraphInput-alldep-withext.txt" -sort ${target_project_name}
131  WORKING_DIRECTORY ${dir}
132  RESULT_VARIABLE RESULT_VAR
133  OUTPUT_VARIABLE dep_path
134  ERROR_VARIABLE error
135  OUTPUT_STRIP_TRAILING_WHITESPACE
136  )
137  if(RESULT_VAR)
138  message(FATAL_ERROR "Failed to obtain dependence path of ${target_project_name}.\n${RESULT_VAR}\n${CTK_BINARY_DIR}\n${error}")
139  endif()
140 
141  # Set a variable for each target containing its dependencies
142  # Needed for setting individual include directories for plugins,
143  # depending on other plugins.
144  set(${target_project_name}_DEPENDENCIES )
145 
146  # Convert 'dep_path' to a list
147  string(REPLACE " " "\\;" dep_path_list ${dep_path})
148  set(dep_path_list ${dep_path_list})
149  list(REMOVE_ITEM dep_path_list ${target_project_name})
150  list(APPEND ${target_project_name}_DEPENDENCIES ${dep_path_list})
151 
152  #message("path for ${target_project_name} is: ${dep_path_list}")
153 
154  # Check if all internal CTK targets included in the dependency path are enabled
155  set(int_dep_path_list )
156  set(ext_dep_path_list ${dep_path_list})
157  ctkMacroGetAllProjectTargetLibraries("${dep_path_list}" int_dep_path_list)
158  if(int_dep_path_list)
159  list(REMOVE_ITEM ext_dep_path_list ${int_dep_path_list})
160  endif()
161 
162  if(ext_dep_path_list)
163  list(APPEND EXTERNAL_TARGETS ${ext_dep_path_list})
164  # If this macro is called from inside CTK itself, we add the external
165  # targets to the list of known targets (for external projects calling
166  # this macro, targets external to the calling project should be listed
167  # in CTK_LIBRARIES or CTK_EXTERNAL_PLUGIN_LIBRARIES
168  if(CTK_SOURCE_DIR)
169  if(${CMAKE_SOURCE_DIR} STREQUAL ${CTK_SOURCE_DIR})
170  list(APPEND known_targets ${ext_dep_path_list})
171  endif()
172  endif()
173  endif()
174 
175  foreach(dep ${int_dep_path_list})
176  list(FIND known_targets ${dep} dep_found)
177  if(dep_found LESS 0)
178  message(FATAL_ERROR "${target_project_name} depends on ${dep}, which does not exist")
179  endif()
180 
181  ctkMacroGetOptionName("${target_directories_with_target_name}" ${dep} dep_option)
182  if(${${option_name}} AND NOT ${${dep_option}})
183  # Enable option
184  message(STATUS "Enabling option [${dep_option}] required by [${target_project_name}]")
185  set(${dep_option} ON CACHE BOOL "Enable ${target_project_name} library" FORCE)
186  endif()
187  endforeach()
188 
189  # For enabled targets, check if all external targets included in the dependency path are available
190  if(${${option_name}})
191  foreach(dep ${ext_dep_path_list})
192  list(FIND known_targets ${dep} dep_found)
193  if(dep_found LESS 0)
194  message(FATAL_ERROR "${target_project_name} depends on unknown external targets: ${dep}")
195  endif()
196  endforeach()
197  endif()
198 
199  endforeach()
200 
201  if(EXTERNAL_TARGETS)
202  list(REMOVE_DUPLICATES EXTERNAL_TARGETS)
203  endif()
204 
205  #message(STATUS "Validated: CTK_LIB_*, CTK_PLUGIN_*, CTK_APP_*")
206 endmacro()