ctkMacroCheckExternalProjectDependency.cmake 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  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. include(CMakeParseArguments)
  21. include(ctkListToString)
  22. if(NOT DEFINED EP_LIST_SEPARATOR)
  23. set(EP_LIST_SEPARATOR "^^")
  24. endif()
  25. if(NOT EXISTS "${EXTERNAL_PROJECT_DIR}")
  26. set(EXTERNAL_PROJECT_DIR ${${CMAKE_PROJECT_NAME}_SOURCE_DIR}/SuperBuild)
  27. endif()
  28. if(NOT DEFINED EXTERNAL_PROJECT_FILE_PREFIX)
  29. set(EXTERNAL_PROJECT_FILE_PREFIX "External_")
  30. endif()
  31. # Compute -G arg for configuring external projects with the same CMake generator:
  32. if(CMAKE_EXTRA_GENERATOR)
  33. set(EP_CMAKE_GENERATOR "${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}")
  34. else()
  35. set(EP_CMAKE_GENERATOR "${CMAKE_GENERATOR}")
  36. endif()
  37. #
  38. # superbuild_include_once()
  39. #
  40. # superbuild_include_once() is a macro intented to be used as include guard.
  41. #
  42. # It ensures that the CMake code placed after the include guard in a CMake file included
  43. # using either 'include(/path/to/file.cmake)' or 'include(cmake_module)' will be executed
  44. # once.
  45. #
  46. # It internally set the global property '<CMAKE_CURRENT_LIST_FILENAME>_FILE_INCLUDED' to check if
  47. # a file has already been included.
  48. #
  49. macro(superbuild_include_once)
  50. # Make sure this file is included only once
  51. get_filename_component(CMAKE_CURRENT_LIST_FILENAME ${CMAKE_CURRENT_LIST_FILE} NAME_WE)
  52. set(_property_name ${CMAKE_CURRENT_LIST_FILENAME}_FILE_INCLUDED)
  53. get_property(${_property_name} GLOBAL PROPERTY ${_property_name})
  54. if(${_property_name})
  55. return()
  56. endif()
  57. set_property(GLOBAL PROPERTY ${_property_name} 1)
  58. endmacro()
  59. #!
  60. #! mark_as_superbuild(<varname1>[:<vartype1>] [<varname2>[:<vartype2>] [...]])
  61. #!
  62. #! mark_as_superbuild(
  63. #! VARS <varname1>[:<vartype1>] [<varname2>[:<vartype2>] [...]]
  64. #! [PROJECTS <projectname> [<projectname> [...]] | ALL_PROJECTS]
  65. #! [LABELS <label1> [<label2> [...]]]
  66. #! [CMAKE_CMD]
  67. #! )
  68. #!
  69. #! PROJECTS corresponds to a list of <projectname> that will be added using 'ExternalProject_Add' function.
  70. #! If not specified and called within a project file, it defaults to the value of 'SUPERBUILD_TOPLEVEL_PROJECT'
  71. #! Otherwise, it defaults to 'CMAKE_PROJECT_NAME'.
  72. #! If instead 'ALL_PROJECTS' is specified, the variables and labels will be passed to all projects.
  73. #!
  74. #! VARS is an expected list of variables specified as <varname>:<vartype> to pass to <projectname>
  75. #!
  76. #!
  77. #! LABELS is an optional list of label to associate with the variable names specified using 'VARS' and passed to
  78. #! the <projectname> as CMake CACHE args of the form:
  79. #! -D<projectname>_EP_LABEL_<label1>=<varname1>;<varname2>[...]
  80. #! -D<projectname>_EP_LABEL_<label2>=<varname1>;<varname2>[...]
  81. #!
  82. function(mark_as_superbuild)
  83. set(options ALL_PROJECTS CMAKE_CMD)
  84. set(oneValueArgs)
  85. set(multiValueArgs VARS PROJECTS LABELS)
  86. cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  87. set(_vars ${_sb_UNPARSED_ARGUMENTS})
  88. set(_named_parameters_expected 0)
  89. if(_sb_PROJECTS OR _sb_ALL_PROJECTS OR _sb_LABELS OR _sb_VARS)
  90. set(_named_parameters_expected 1)
  91. set(_vars ${_sb_VARS})
  92. endif()
  93. if(_named_parameters_expected AND _sb_UNPARSED_ARGUMENTS)
  94. message(FATAL_ERROR "Arguments '${_sb_UNPARSED_ARGUMENTS}' should be associated with VARS parameter !")
  95. endif()
  96. if(_sb_PROJECTS AND _sb_ALL_PROJECTS)
  97. message(FATAL_ERROR "Arguments 'PROJECTS' and 'ALL_PROJECTS' are mutually exclusive !")
  98. endif()
  99. foreach(var ${_vars})
  100. set(_type_specified 0)
  101. if(var MATCHES ":")
  102. set(_type_specified 1)
  103. endif()
  104. # XXX Display warning with variable type is also specified for cache variable.
  105. set(_var ${var})
  106. if(NOT _type_specified)
  107. get_property(_type_set_in_cache CACHE ${_var} PROPERTY TYPE SET)
  108. set(_var_name ${_var})
  109. set(_var_type "STRING")
  110. if(_type_set_in_cache)
  111. get_property(_var_type CACHE ${_var_name} PROPERTY TYPE)
  112. endif()
  113. set(_var ${_var_name}:${_var_type})
  114. endif()
  115. list(APPEND _vars_with_type ${_var})
  116. endforeach()
  117. if(_sb_CMAKE_CMD)
  118. set(optional_arg_CMAKE_CMD "CMAKE_CMD")
  119. endif()
  120. if(_sb_ALL_PROJECTS)
  121. set(optional_arg_ALL_PROJECTS "ALL_PROJECTS")
  122. else()
  123. set(optional_arg_ALL_PROJECTS PROJECTS ${_sb_PROJECTS})
  124. endif()
  125. _sb_append_to_cmake_args(
  126. VARS ${_vars_with_type} LABELS ${_sb_LABELS} ${optional_arg_ALL_PROJECTS} ${optional_arg_CMAKE_CMD})
  127. endfunction()
  128. #!
  129. #! _sb_extract_varname_and_vartype(<cmake_varname_and_type> <varname_var> [<vartype_var>])
  130. #!
  131. #! <cmake_varname_and_type> corresponds to variable name and variable type passed as "<varname>:<vartype>"
  132. #!
  133. #! <varname_var> will be set to "<varname>"
  134. #!
  135. #! <vartype_var> is an optional variable name that will be set to "<vartype>"
  136. function(_sb_extract_varname_and_vartype cmake_varname_and_type varname_var)
  137. set(_vartype_var "${ARGV2}")
  138. string(REPLACE ":" ";" varname_and_vartype ${cmake_varname_and_type})
  139. list(GET varname_and_vartype 0 _varname)
  140. list(GET varname_and_vartype 1 _vartype)
  141. set(${varname_var} ${_varname} PARENT_SCOPE)
  142. if(_vartype_var MATCHES ".+")
  143. set(${_vartype_var} ${_vartype} PARENT_SCOPE)
  144. endif()
  145. endfunction()
  146. #!
  147. #! _sb_cmakevar_to_cmakearg(<cmake_varname_and_type> <cmake_arg_var> <cmake_arg_type> [<varname_var> [<vartype_var>]])
  148. #!
  149. #! <cmake_varname_and_type> corresponds to variable name and variable type passed as "<varname>:<vartype>"
  150. #!
  151. #! <cmake_arg_var> is a variable name that will be set to "-D<varname>:<vartype>=${<varname>}"
  152. #!
  153. #! <cmake_arg_type> is set to either CMAKE_CACHE or CMAKE_CMD.
  154. #! CMAKE_CACHE means that the generated cmake argument will be passed to
  155. #! ExternalProject_Add as CMAKE_CACHE_ARGS.
  156. #! CMAKE_CMD means that the generated cmake argument will be passed to
  157. #! ExternalProject_Add as CMAKE_ARGS.
  158. #!
  159. #! <varname_var> is an optional variable name that will be set to "<varname>"
  160. #!
  161. #! <vartype_var> is an optional variable name that will be set to "<vartype>"
  162. function(_sb_cmakevar_to_cmakearg cmake_varname_and_type cmake_arg_var cmake_arg_type)
  163. set(_varname_var "${ARGV3}")
  164. set(_vartype_var "${ARGV4}")
  165. # XXX Add check for <cmake_arg_type> value
  166. _sb_extract_varname_and_vartype(${cmake_varname_and_type} _varname _vartype)
  167. set(_var_value "${${_varname}}")
  168. get_property(_value_set_in_cache CACHE ${_varname} PROPERTY VALUE SET)
  169. if(_value_set_in_cache)
  170. get_property(_var_value CACHE ${_varname} PROPERTY VALUE)
  171. endif()
  172. if(cmake_arg_type STREQUAL "CMAKE_CMD")
  173. # Separate list item with <EP_LIST_SEPARATOR>
  174. ctk_list_to_string(${EP_LIST_SEPARATOR} "${_var_value}" _var_value)
  175. endif()
  176. set(${cmake_arg_var} -D${_varname}:${_vartype}=${_var_value} PARENT_SCOPE)
  177. if(_varname_var MATCHES ".+")
  178. set(${_varname_var} ${_varname} PARENT_SCOPE)
  179. endif()
  180. if(_vartype_var MATCHES ".+")
  181. set(${_vartype_var} ${_vartype} PARENT_SCOPE)
  182. endif()
  183. endfunction()
  184. set(_ALL_PROJECT_IDENTIFIER "ALLALLALL")
  185. #!
  186. #! _sb_append_to_cmake_args(
  187. #! VARS <varname1>:<vartype1> [<varname2>:<vartype2> [...]]
  188. #! [PROJECTS <projectname> [<projectname> [...]] | ALL_PROJECTS]
  189. #! [LABELS <label1> [<label2> [...]]]
  190. #! [CMAKE_CMD]
  191. #! )
  192. #!
  193. #! PROJECTS corresponds to a list of <projectname> that will be added using 'ExternalProject_Add' function.
  194. #! If not specified and called within a project file, it defaults to the value of 'SUPERBUILD_TOPLEVEL_PROJECT'
  195. #! Otherwise, it defaults to 'CMAKE_PROJECT_NAME'.
  196. #! If instead 'ALL_PROJECTS' is specified, the variables and labels will be passed to all projects.
  197. #!
  198. #! VARS is an expected list of variables specified as <varname>:<vartype> to pass to <projectname>
  199. #!
  200. #!
  201. #! LABELS is an optional list of label to associate with the variable names specified using 'VARS' and passed to
  202. #! the <projectname> as CMake CACHE args of the form:
  203. #! -D<projectname>_EP_LABEL_<label1>=<varname1>;<varname2>[...]
  204. #! -D<projectname>_EP_LABEL_<label2>=<varname1>;<varname2>[...]
  205. #!
  206. function(_sb_append_to_cmake_args)
  207. set(options ALL_PROJECTS CMAKE_CMD)
  208. set(oneValueArgs)
  209. set(multiValueArgs VARS PROJECTS LABELS)
  210. cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  211. if(NOT _sb_PROJECTS AND NOT _sb_ALL_PROJECTS)
  212. if(SUPERBUILD_TOPLEVEL_PROJECT)
  213. set(_sb_PROJECTS ${SUPERBUILD_TOPLEVEL_PROJECT})
  214. else()
  215. set(_sb_PROJECTS ${CMAKE_PROJECT_NAME})
  216. endif()
  217. endif()
  218. if(_sb_ALL_PROJECTS)
  219. set(_sb_PROJECTS ${_ALL_PROJECT_IDENTIFIER})
  220. endif()
  221. foreach(_sb_PROJECT ${_sb_PROJECTS})
  222. set(_cmake_arg_type "CMAKE_CACHE")
  223. if(_sb_CMAKE_CMD)
  224. set(_cmake_arg_type "CMAKE")
  225. set(optional_arg_CMAKE_CMD "CMAKE_CMD")
  226. endif()
  227. set(_ep_property "${_cmake_arg_type}_ARGS")
  228. set(_ep_varnames "")
  229. foreach(varname_and_vartype ${_sb_VARS})
  230. if(NOT TARGET ${_sb_PROJECT})
  231. set_property(GLOBAL APPEND PROPERTY ${_sb_PROJECT}_EP_${_ep_property} ${varname_and_vartype})
  232. _sb_extract_varname_and_vartype(${varname_and_vartype} _varname)
  233. else()
  234. message(FATAL_ERROR "Function _sb_append_to_cmake_args not allowed is project already added !")
  235. endif()
  236. list(APPEND _ep_varnames ${_varname})
  237. endforeach()
  238. if(_sb_LABELS)
  239. set_property(GLOBAL APPEND PROPERTY ${_sb_PROJECT}_EP_LABELS ${_sb_LABELS})
  240. foreach(label ${_sb_LABELS})
  241. set_property(GLOBAL APPEND PROPERTY ${_sb_PROJECT}_EP_LABEL_${label} ${_ep_varnames})
  242. endforeach()
  243. endif()
  244. endforeach()
  245. endfunction()
  246. function(_sb_get_external_project_arguments proj varname)
  247. mark_as_superbuild(${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj}:BOOL)
  248. function(_sb_collect_args proj)
  249. # Set list of CMake args associated with each label
  250. get_property(_labels GLOBAL PROPERTY ${proj}_EP_LABELS)
  251. if(_labels)
  252. list(REMOVE_DUPLICATES _labels)
  253. foreach(label ${_labels})
  254. get_property(${proj}_EP_LABEL_${label} GLOBAL PROPERTY ${proj}_EP_LABEL_${label})
  255. list(REMOVE_DUPLICATES ${proj}_EP_LABEL_${label})
  256. _sb_append_to_cmake_args(PROJECTS ${proj}
  257. VARS ${proj}_EP_LABEL_${label}:STRING)
  258. endforeach()
  259. endif()
  260. foreach(cmake_arg_type CMAKE_CMD CMAKE_CACHE)
  261. set(_ep_property "CMAKE_CACHE_ARGS")
  262. if(cmake_arg_type STREQUAL "CMAKE_CMD")
  263. set(_ep_property "CMAKE_ARGS")
  264. endif()
  265. get_property(_args GLOBAL PROPERTY ${proj}_EP_${_ep_property})
  266. foreach(var ${_args})
  267. _sb_cmakevar_to_cmakearg(${var} cmake_arg ${cmake_arg_type})
  268. set_property(GLOBAL APPEND PROPERTY ${proj}_EP_PROPERTY_${_ep_property} ${cmake_arg})
  269. endforeach()
  270. endforeach()
  271. endfunction()
  272. _sb_collect_args(${proj})
  273. _sb_collect_args(${_ALL_PROJECT_IDENTIFIER})
  274. set(_ep_arguments "")
  275. foreach(property CMAKE_ARGS CMAKE_CACHE_ARGS)
  276. get_property(${proj}_EP_PROPERTY_${property} GLOBAL PROPERTY ${proj}_EP_PROPERTY_${property})
  277. get_property(${_ALL_PROJECT_IDENTIFIER}_EP_PROPERTY_${property} GLOBAL PROPERTY ${_ALL_PROJECT_IDENTIFIER}_EP_PROPERTY_${property})
  278. if(${proj}_EP_PROPERTY_${property} OR ${_ALL_PROJECT_IDENTIFIER}_EP_PROPERTY_${property})
  279. list(APPEND _ep_arguments ${property}
  280. ${${proj}_EP_PROPERTY_${property}} ${${_ALL_PROJECT_IDENTIFIER}_EP_PROPERTY_${property}})
  281. endif()
  282. endforeach()
  283. list(APPEND _ep_arguments LIST_SEPARATOR ${EP_LIST_SEPARATOR})
  284. list(APPEND _ep_arguments CMAKE_GENERATOR ${EP_CMAKE_GENERATOR})
  285. set(${varname} ${_ep_arguments} PARENT_SCOPE)
  286. endfunction()
  287. function(_sb_update_indent proj)
  288. superbuild_stack_size(SUPERBUILD_PROJECT_STACK _stack_size)
  289. set(_indent "")
  290. if(_stack_size GREATER 0)
  291. foreach(not_used RANGE 1 ${_stack_size})
  292. set(_indent " ${_indent}")
  293. endforeach()
  294. endif()
  295. set_property(GLOBAL PROPERTY SUPERBUILD_${proj}_INDENT ${_indent})
  296. endfunction()
  297. function(superbuild_message proj msg)
  298. if(NOT SUPERBUILD_FIRST_PASS)
  299. get_property(_indent GLOBAL PROPERTY SUPERBUILD_${proj}_INDENT)
  300. message(STATUS "SuperBuild - ${_indent}${msg}")
  301. endif()
  302. endfunction()
  303. #!
  304. #! superbuild_stack_content(<stack_name> <output_var>)
  305. #!
  306. #! <stack_name> corresponds to the name of stack.
  307. #!
  308. #! <output_var> is the name of CMake variable that will be set with the content
  309. #! of the stack identified by <stack_name>.
  310. function(superbuild_stack_content stack_name output_var)
  311. get_property(_stack GLOBAL PROPERTY ${stack_name})
  312. set(${output_var} ${_stack} PARENT_SCOPE)
  313. endfunction()
  314. #!
  315. #! superbuild_stack_size(<stack_name> <output_var>)
  316. #!
  317. #! <stack_name> corresponds to the name of stack.
  318. #!
  319. #! <output_var> is the name of CMake variable that will be set with the size
  320. #! of the stack identified by <stack_name>.
  321. function(superbuild_stack_size stack_name output_var)
  322. get_property(_stack GLOBAL PROPERTY ${stack_name})
  323. list(LENGTH _stack _stack_size)
  324. set(${output_var} ${_stack_size} PARENT_SCOPE)
  325. endfunction()
  326. #!
  327. #! superbuild_stack_push(<stack_name> <value>)
  328. #!
  329. #! <stack_name> corresponds to the name of stack.
  330. #!
  331. #! <value> is appended to the stack identified by <stack_name>.
  332. function(superbuild_stack_push stack_name value)
  333. set_property(GLOBAL APPEND PROPERTY ${stack_name} ${value})
  334. endfunction()
  335. #!
  336. #! superbuild_stack_pop(<stack_name> <item_var>)
  337. #!
  338. #! <stack_name> corresponds to the name of stack.
  339. #!
  340. #! <item_var> names a CMake variable that will be set with the item
  341. #! removed from the stack identified by <stack_name>.
  342. function(superbuild_stack_pop stack_name item_var)
  343. get_property(_stack GLOBAL PROPERTY ${stack_name})
  344. list(LENGTH _stack _stack_size)
  345. if(_stack_size GREATER 0)
  346. math(EXPR _index_to_remove "${_stack_size} - 1")
  347. list(GET _stack ${_index_to_remove} _item)
  348. list(REMOVE_AT _stack ${_index_to_remove})
  349. set_property(GLOBAL PROPERTY ${stack_name} ${_stack})
  350. set(${item_var} ${_item} PARENT_SCOPE)
  351. endif()
  352. endfunction()
  353. #
  354. # superbuild_include_dependencies(<project>)
  355. #
  356. # superbuild_include_dependencies(PROJECT_VAR <project_var>)
  357. #
  358. macro(superbuild_include_dependencies)
  359. set(options)
  360. set(oneValueArgs PROJECT_VAR)
  361. set(multiValueArgs)
  362. cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  363. # XXX Implement invalid parameter checking
  364. if(NOT "x" STREQUAL "x${_sb_PROJECT_VAR}")
  365. set(proj ${${_sb_PROJECT_VAR}})
  366. else()
  367. set(proj ${_sb_UNPARSED_ARGUMENTS})
  368. endif()
  369. # Sanity checks
  370. if(NOT DEFINED ${proj}_DEPENDENCIES)
  371. message(FATAL_ERROR "${proj}_DEPENDENCIES variable is NOT defined !")
  372. endif()
  373. superbuild_stack_size(SUPERBUILD_PROJECT_STACK _stack_size)
  374. if(_stack_size EQUAL 0)
  375. set(SUPERBUILD_TOPLEVEL_PROJECT ${proj})
  376. endif()
  377. _sb_update_indent(${proj})
  378. # Keep track of the projects
  379. list(APPEND __epd_${SUPERBUILD_TOPLEVEL_PROJECT}_projects ${proj})
  380. # Is this the first run ? (used to set the <SUPERBUILD_TOPLEVEL_PROJECT>_USE_SYSTEM_* variables)
  381. if(${proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT} AND NOT DEFINED SUPERBUILD_FIRST_PASS)
  382. message(STATUS "SuperBuild - First pass")
  383. set(SUPERBUILD_FIRST_PASS TRUE)
  384. endif()
  385. # Display dependency of project being processed
  386. if("${${proj}_DEPENDENCIES}" STREQUAL "")
  387. set(_msg "${proj}[OK]")
  388. if(${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj})
  389. set(_msg "${_msg} (SYSTEM)")
  390. endif()
  391. superbuild_message(${proj} ${_msg})
  392. else()
  393. set(dependency_str " ")
  394. foreach(dep ${${proj}_DEPENDENCIES})
  395. get_property(_is_included GLOBAL PROPERTY ${EXTERNAL_PROJECT_FILE_PREFIX}${dep}_FILE_INCLUDED)
  396. if(_is_included)
  397. set(dependency_str "${dependency_str}${dep}[INCLUDED], ")
  398. else()
  399. set(dependency_str "${dependency_str}${dep}, ")
  400. endif()
  401. endforeach()
  402. superbuild_message(${proj} "${proj} => Requires${dependency_str}")
  403. endif()
  404. if(NOT ${proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT})
  405. foreach(dep ${${proj}_DEPENDENCIES})
  406. if(${${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj}})
  407. set(${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${dep} ${${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj}})
  408. endif()
  409. #if(SUPERBUILD_FIRST_PASS)
  410. # message("${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${dep} set to "
  411. # "[${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj}:${${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj}}]")
  412. #endif()
  413. endforeach()
  414. endif()
  415. superbuild_stack_push(SUPERBUILD_PROJECT_STACK ${proj})
  416. # Include dependencies
  417. foreach(dep ${${proj}_DEPENDENCIES})
  418. get_property(_is_included GLOBAL PROPERTY External_${dep}_FILE_INCLUDED)
  419. if(NOT _is_included)
  420. # XXX - Refactor - Add a single variable named 'EXTERNAL_PROJECT_DIRS'
  421. if(EXISTS "${EXTERNAL_PROJECT_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake")
  422. include(${EXTERNAL_PROJECT_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake)
  423. elseif(EXISTS "${${dep}_FILEPATH}")
  424. include(${${dep}_FILEPATH})
  425. elseif(EXISTS "${EXTERNAL_PROJECT_ADDITIONAL_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake")
  426. include(${EXTERNAL_PROJECT_ADDITIONAL_DIR}/${EXTERNAL_PEXCLUDEDROJECT_FILE_PREFIX}${dep}.cmake)
  427. else()
  428. message(FATAL_ERROR "Can't find ${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake")
  429. endif()
  430. endif()
  431. endforeach()
  432. superbuild_stack_pop(SUPERBUILD_PROJECT_STACK proj)
  433. # If project being process has dependencies, indicates it has also been added.
  434. if(NOT "${${proj}_DEPENDENCIES}" STREQUAL "")
  435. set(_msg "${proj}[OK]")
  436. if(${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj})
  437. set(_msg "${_msg} (SYSTEM)")
  438. endif()
  439. superbuild_message(${proj} ${_msg})
  440. endif()
  441. if(${proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT} AND SUPERBUILD_FIRST_PASS)
  442. message(STATUS "SuperBuild - First pass - done")
  443. unset(${SUPERBUILD_TOPLEVEL_PROJECT}_DEPENDENCIES) # XXX - Refactor
  444. set(SUPERBUILD_FIRST_PASS FALSE)
  445. foreach(possible_proj ${__epd_${SUPERBUILD_TOPLEVEL_PROJECT}_projects})
  446. set_property(GLOBAL PROPERTY ${EXTERNAL_PROJECT_FILE_PREFIX}${possible_proj}_FILE_INCLUDED 0)
  447. if(NOT ${possible_proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT})
  448. set(_include_project 1)
  449. if(COMMAND superbuild_is_external_project_includable)
  450. superbuild_is_external_project_includable("${possible_proj}" _include_project)
  451. endif()
  452. if(_include_project)
  453. list(APPEND ${SUPERBUILD_TOPLEVEL_PROJECT}_DEPENDENCIES ${possible_proj})
  454. else()
  455. if(${SUPERBUILD_TOPLEVEL_PROJECT}_SUPERBUILD)
  456. superbuild_message(STATUS "${possible_proj}[OPTIONAL]")
  457. endif()
  458. endif()
  459. endif()
  460. endforeach()
  461. list(REMOVE_DUPLICATES ${SUPERBUILD_TOPLEVEL_PROJECT}_DEPENDENCIES)
  462. if(${SUPERBUILD_TOPLEVEL_PROJECT}_SUPERBUILD)
  463. superbuild_include_dependencies(${SUPERBUILD_TOPLEVEL_PROJECT})
  464. endif()
  465. set(SUPERBUILD_FIRST_PASS TRUE)
  466. endif()
  467. if(_sb_PROJECT_VAR)
  468. set(${_sb_PROJECT_VAR} ${proj})
  469. endif()
  470. if(SUPERBUILD_FIRST_PASS)
  471. if(NOT ${proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT})
  472. return()
  473. endif()
  474. else()
  475. unset(${proj}_EXTERNAL_PROJECT_ARGS)
  476. _sb_get_external_project_arguments(${proj} ${proj}_EXTERNAL_PROJECT_ARGS)
  477. #message("${proj}_EXTERNAL_PROJECT_ARGS:${${proj}_EXTERNAL_PROJECT_ARGS}")
  478. endif()
  479. endmacro()
  480. #!
  481. #! Convenient macro allowing to define a "empty" project in case an external one is provided
  482. #! using for example <proj>_DIR.
  483. #! Doing so allows to keep the external project dependency system happy.
  484. #!
  485. #! \ingroup CMakeUtilities
  486. macro(superbuild_add_empty_external_project proj dependencies)
  487. ExternalProject_Add(${proj}
  488. SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}
  489. BINARY_DIR ${proj}-build
  490. DOWNLOAD_COMMAND ""
  491. CONFIGURE_COMMAND ""
  492. BUILD_COMMAND ""
  493. INSTALL_COMMAND ""
  494. DEPENDS
  495. ${dependencies}
  496. )
  497. endmacro()