ctkMacroCheckExternalProjectDependency.cmake 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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. if(NOT EXISTS "${EXTERNAL_PROJECT_DIR}")
  21. set(EXTERNAL_PROJECT_DIR ${${CMAKE_PROJECT_NAME}_SOURCE_DIR}/SuperBuild)
  22. endif()
  23. if(NOT DEFINED EXTERNAL_PROJECT_FILE_PREFIX)
  24. set(EXTERNAL_PROJECT_FILE_PREFIX "External_")
  25. endif()
  26. #
  27. # superbuild_include_once()
  28. #
  29. # superbuild_include_once() is a macro intented to be used as include guard.
  30. #
  31. # It ensures that the CMake code placed after the include guard in a CMake file included
  32. # using either 'include(/path/to/file.cmake)' or 'include(cmake_module)' will be executed
  33. # once.
  34. #
  35. # It internally set the global property '<CMAKE_CURRENT_LIST_FILENAME>_FILE_INCLUDED' to check if
  36. # a file has already been included.
  37. #
  38. macro(superbuild_include_once)
  39. # Make sure this file is included only once
  40. get_filename_component(CMAKE_CURRENT_LIST_FILENAME ${CMAKE_CURRENT_LIST_FILE} NAME_WE)
  41. set(_property_name ${CMAKE_CURRENT_LIST_FILENAME}_FILE_INCLUDED)
  42. get_property(${_property_name} GLOBAL PROPERTY ${_property_name})
  43. if(${_property_name})
  44. return()
  45. endif()
  46. set_property(GLOBAL PROPERTY ${_property_name} 1)
  47. endmacro()
  48. #!
  49. #! superbuild_cmakevar_to_cmakearg(<cmake_varname_and_type> <cmake_arg_var> <cmake_arg_type> [<varname_var> [<vartype_var>]])
  50. #!
  51. #! <cmake_varname_and_type> corresponds to variable name and variable type passed as "<varname>:<vartype>"
  52. #!
  53. #! <cmake_arg_var> is a variable name that will be set to "-D<varname>:<vartype>=${<varname>}"
  54. #!
  55. #! <cmake_arg_type> is set to either CMAKE_CACHE or CMAKE_CMD.
  56. #! CMAKE_CACHE means that the generated cmake argument will be passed to
  57. #! ExternalProject_Add as CMAKE_CACHE_ARGS.
  58. #! CMAKE_CMD means that the generated cmake argument will be passed to
  59. #! ExternalProject_Add as CMAKE_ARGS.
  60. #!
  61. #! <varname_var> is an optional variable name that will be set to "<varname>"
  62. #!
  63. #! <vartype_var> is an optional variable name that will be set to "<vartype>"
  64. function(superbuild_cmakevar_to_cmakearg cmake_varname_and_type cmake_arg_var cmake_arg_type)
  65. set(_varname_var ${ARGV3})
  66. set(_vartype_var ${ARGV4})
  67. string(REPLACE ":" ";" varname_and_vartype ${cmake_varname_and_type})
  68. list(GET varname_and_vartype 0 _varname)
  69. list(GET varname_and_vartype 1 _vartype)
  70. set(_var_value "${${_varname}}")
  71. get_property(_value_set_in_cache CACHE ${_varname} PROPERTY VALUE SET)
  72. if(_value_set_in_cache)
  73. get_property(_var_value CACHE ${_varname} PROPERTY VALUE)
  74. endif()
  75. # XXX Add check for <cmake_arg_type> value
  76. if(cmake_arg_type STREQUAL "CMAKE_CMD")
  77. # Separate list item with <sep>
  78. set(ep_arg_as_string "")
  79. ctk_list_to_string(${sep} "${_var_value}" _var_value)
  80. endif()
  81. set(${cmake_arg_var} -D${_varname}:${_vartype}=${_var_value} PARENT_SCOPE)
  82. if(_varname_var MATCHES ".+")
  83. set(${_varname_var} ${_varname} PARENT_SCOPE)
  84. endif()
  85. if(_vartype_var MATCHES ".+")
  86. set(${_vartype_var} ${_vartype} PARENT_SCOPE)
  87. endif()
  88. endfunction()
  89. macro(_epd_status txt)
  90. if(NOT __epd_first_pass)
  91. message(STATUS ${txt})
  92. endif()
  93. endmacro()
  94. macro(ctkMacroCheckExternalProjectDependency proj)
  95. # Set indent variable if needed
  96. if(NOT DEFINED __indent)
  97. set(__indent "")
  98. else()
  99. set(__indent "${__indent} ")
  100. endif()
  101. # Sanity checks
  102. if(NOT DEFINED ${proj}_DEPENDENCIES)
  103. message(FATAL_ERROR "${__indent}${proj}_DEPENDENCIES variable is NOT defined !")
  104. endif()
  105. if(NOT DEFINED SUPERBUILD_TOPLEVEL_PROJECT)
  106. set(SUPERBUILD_TOPLEVEL_PROJECT ${proj})
  107. endif()
  108. # Keep track of the projects
  109. list(APPEND __epd_${SUPERBUILD_TOPLEVEL_PROJECT}_projects ${proj})
  110. # Is this the first run ? (used to set the <SUPERBUILD_TOPLEVEL_PROJECT>_USE_SYSTEM_* variables)
  111. if(${proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT} AND NOT DEFINED __epd_first_pass)
  112. message(STATUS "SuperBuild - First pass")
  113. set(__epd_first_pass TRUE)
  114. endif()
  115. # Set message strings
  116. set(__${proj}_indent ${__indent})
  117. set(__${proj}_superbuild_message "SuperBuild - ${__indent}${proj}[OK]")
  118. if(${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj})
  119. set(__${proj}_superbuild_message "${__${proj}_superbuild_message} (SYSTEM)")
  120. endif()
  121. # Display dependency of project being processed
  122. if("${${proj}_DEPENDENCIES}" STREQUAL "")
  123. _epd_status(${__${proj}_superbuild_message})
  124. else()
  125. set(dependency_str " ")
  126. foreach(dep ${${proj}_DEPENDENCIES})
  127. get_property(_is_included GLOBAL PROPERTY ${EXTERNAL_PROJECT_FILE_PREFIX}${dep}_FILE_INCLUDED)
  128. if(_is_included)
  129. set(dependency_str "${dependency_str}${dep}[INCLUDED], ")
  130. else()
  131. set(dependency_str "${dependency_str}${dep}, ")
  132. endif()
  133. endforeach()
  134. _epd_status("SuperBuild - ${__indent}${proj} => Requires${dependency_str}")
  135. endif()
  136. foreach(dep ${${proj}_DEPENDENCIES})
  137. if(${${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj}})
  138. set(${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${dep} ${${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj}})
  139. endif()
  140. #if(__epd_first_pass)
  141. # message("${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${dep} set to [${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj}:${${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj}}]")
  142. #endif()
  143. endforeach()
  144. # Include dependencies
  145. foreach(dep ${${proj}_DEPENDENCIES})
  146. get_property(_is_included GLOBAL PROPERTY External_${dep}_FILE_INCLUDED)
  147. if(NOT _is_included)
  148. # XXX - Refactor - Add a single variable named 'EXTERNAL_PROJECT_DIRS'
  149. if(EXISTS "${EXTERNAL_PROJECT_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake")
  150. include(${EXTERNAL_PROJECT_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake)
  151. elseif(EXISTS "${${dep}_FILEPATH}")
  152. include(${${dep}_FILEPATH})
  153. elseif(EXISTS "${EXTERNAL_PROJECT_ADDITIONAL_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake")
  154. include(${EXTERNAL_PROJECT_ADDITIONAL_DIR}/${EXTERNAL_PEXCLUDEDROJECT_FILE_PREFIX}${dep}.cmake)
  155. else()
  156. message(FATAL_ERROR "Can't find ${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake")
  157. endif()
  158. endif()
  159. endforeach()
  160. # If project being process has dependencies, indicates it has also been added.
  161. if(NOT "${${proj}_DEPENDENCIES}" STREQUAL "")
  162. _epd_status(${__${proj}_superbuild_message})
  163. endif()
  164. # Update indent variable
  165. string(LENGTH "${__indent}" __indent_length)
  166. math(EXPR __indent_length "${__indent_length}-2")
  167. if(NOT ${__indent_length} LESS 0)
  168. string(SUBSTRING "${__indent}" 0 ${__indent_length} __indent)
  169. endif()
  170. if(${proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT} AND __epd_first_pass)
  171. message(STATUS "SuperBuild - First pass - done")
  172. unset(__indent)
  173. if(${SUPERBUILD_TOPLEVEL_PROJECT}_SUPERBUILD)
  174. set(__epd_first_pass FALSE)
  175. endif()
  176. unset(${SUPERBUILD_TOPLEVEL_PROJECT}_DEPENDENCIES) # XXX - Refactor
  177. foreach(possible_proj ${__epd_${SUPERBUILD_TOPLEVEL_PROJECT}_projects})
  178. if(NOT ${possible_proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT})
  179. set_property(GLOBAL PROPERTY ${EXTERNAL_PROJECT_FILE_PREFIX}${possible_proj}_FILE_INCLUDED 0)
  180. # XXX - Refactor - The following code should be re-organized
  181. if(DEFINED ${possible_proj}_enabling_variable)
  182. ctkMacroShouldAddExternalproject(${${possible_proj}_enabling_variable} add_project)
  183. if(${add_project})
  184. list(APPEND ${SUPERBUILD_TOPLEVEL_PROJECT}_DEPENDENCIES ${possible_proj})
  185. else()
  186. # XXX HACK
  187. if(${possible_proj} STREQUAL "VTK"
  188. AND CTK_LIB_Scripting/Python/Core_PYTHONQT_USE_VTK)
  189. list(APPEND ${SUPERBUILD_TOPLEVEL_PROJECT}_DEPENDENCIES VTK)
  190. else()
  191. unset(${${possible_proj}_enabling_variable}_INCLUDE_DIRS)
  192. unset(${${possible_proj}_enabling_variable}_LIBRARY_DIRS)
  193. unset(${${possible_proj}_enabling_variable}_FIND_PACKAGE_CMD)
  194. if(${SUPERBUILD_TOPLEVEL_PROJECT}_SUPERBUILD)
  195. message(STATUS "SuperBuild - ${possible_proj}[OPTIONAL]")
  196. endif()
  197. endif()
  198. endif()
  199. else()
  200. list(APPEND ${SUPERBUILD_TOPLEVEL_PROJECT}_DEPENDENCIES ${possible_proj})
  201. endif()
  202. # XXX
  203. else()
  204. endif()
  205. endforeach()
  206. list(REMOVE_DUPLICATES ${SUPERBUILD_TOPLEVEL_PROJECT}_DEPENDENCIES)
  207. if(${SUPERBUILD_TOPLEVEL_PROJECT}_SUPERBUILD)
  208. ctkMacroCheckExternalProjectDependency(${SUPERBUILD_TOPLEVEL_PROJECT})
  209. endif()
  210. endif()
  211. if(__epd_first_pass)
  212. return()
  213. endif()
  214. endmacro()