ctkMacroCheckExternalProjectDependency.cmake 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  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. if(NOT DEFINED EP_LIST_SEPARATOR)
  22. set(EP_LIST_SEPARATOR "^^")
  23. endif()
  24. if(NOT EXISTS "${EXTERNAL_PROJECT_DIR}")
  25. set(EXTERNAL_PROJECT_DIR ${CMAKE_SOURCE_DIR}/SuperBuild)
  26. endif()
  27. if(NOT DEFINED EXTERNAL_PROJECT_FILE_PREFIX)
  28. set(EXTERNAL_PROJECT_FILE_PREFIX "External_")
  29. endif()
  30. # Compute -G arg for configuring external projects with the same CMake generator:
  31. if(CMAKE_EXTRA_GENERATOR)
  32. set(EP_CMAKE_GENERATOR "${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}")
  33. else()
  34. set(EP_CMAKE_GENERATOR "${CMAKE_GENERATOR}")
  35. endif()
  36. #!
  37. #! mark_as_superbuild(<varname1>[:<vartype1>] [<varname2>[:<vartype2>] [...]])
  38. #!
  39. #! mark_as_superbuild(
  40. #! VARS <varname1>[:<vartype1>] [<varname2>[:<vartype2>] [...]]
  41. #! [PROJECTS <projectname> [<projectname> [...]] | ALL_PROJECTS]
  42. #! [LABELS <label1> [<label2> [...]]]
  43. #! [CMAKE_CMD]
  44. #! )
  45. #!
  46. #! PROJECTS corresponds to a list of <projectname> that will be added using 'ExternalProject_Add' function.
  47. #! If not specified and called within a project file, it defaults to the value of 'SUPERBUILD_TOPLEVEL_PROJECT'
  48. #! Otherwise, it defaults to 'CMAKE_PROJECT_NAME'.
  49. #! If instead 'ALL_PROJECTS' is specified, the variables and labels will be passed to all projects.
  50. #!
  51. #! VARS is an expected list of variables specified as <varname>:<vartype> to pass to <projectname>
  52. #!
  53. #!
  54. #! LABELS is an optional list of label to associate with the variable names specified using 'VARS' and passed to
  55. #! the <projectname> as CMake CACHE args of the form:
  56. #! -D<projectname>_EP_LABEL_<label1>=<varname1>;<varname2>[...]
  57. #! -D<projectname>_EP_LABEL_<label2>=<varname1>;<varname2>[...]
  58. #!
  59. function(mark_as_superbuild)
  60. set(options ALL_PROJECTS CMAKE_CMD)
  61. set(oneValueArgs)
  62. set(multiValueArgs VARS PROJECTS LABELS)
  63. cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  64. set(_vars ${_sb_UNPARSED_ARGUMENTS})
  65. set(_named_parameters_expected 0)
  66. if(_sb_PROJECTS OR _sb_ALL_PROJECTS OR _sb_LABELS OR _sb_VARS)
  67. set(_named_parameters_expected 1)
  68. set(_vars ${_sb_VARS})
  69. endif()
  70. if(_named_parameters_expected AND _sb_UNPARSED_ARGUMENTS)
  71. message(FATAL_ERROR "Arguments '${_sb_UNPARSED_ARGUMENTS}' should be associated with VARS parameter !")
  72. endif()
  73. if(_sb_PROJECTS AND _sb_ALL_PROJECTS)
  74. message(FATAL_ERROR "Arguments 'PROJECTS' and 'ALL_PROJECTS' are mutually exclusive !")
  75. endif()
  76. foreach(var ${_vars})
  77. set(_type_specified 0)
  78. if(var MATCHES ":")
  79. set(_type_specified 1)
  80. endif()
  81. # XXX Display warning with variable type is also specified for cache variable.
  82. set(_var ${var})
  83. if(NOT _type_specified)
  84. get_property(_type_set_in_cache CACHE ${_var} PROPERTY TYPE SET)
  85. set(_var_name ${_var})
  86. set(_var_type "STRING")
  87. if(_type_set_in_cache)
  88. get_property(_var_type CACHE ${_var_name} PROPERTY TYPE)
  89. endif()
  90. set(_var ${_var_name}:${_var_type})
  91. endif()
  92. list(APPEND _vars_with_type ${_var})
  93. endforeach()
  94. if(_sb_CMAKE_CMD)
  95. set(optional_arg_CMAKE_CMD "CMAKE_CMD")
  96. endif()
  97. if(_sb_ALL_PROJECTS)
  98. set(optional_arg_ALL_PROJECTS "ALL_PROJECTS")
  99. else()
  100. set(optional_arg_ALL_PROJECTS PROJECTS ${_sb_PROJECTS})
  101. endif()
  102. _sb_append_to_cmake_args(
  103. VARS ${_vars_with_type} LABELS ${_sb_LABELS} ${optional_arg_ALL_PROJECTS} ${optional_arg_CMAKE_CMD})
  104. endfunction()
  105. #!
  106. #! _sb_extract_varname_and_vartype(<cmake_varname_and_type> <varname_var> [<vartype_var>])
  107. #!
  108. #! <cmake_varname_and_type> corresponds to variable name and variable type passed as "<varname>:<vartype>"
  109. #!
  110. #! <varname_var> will be set to "<varname>"
  111. #!
  112. #! <vartype_var> is an optional variable name that will be set to "<vartype>"
  113. function(_sb_extract_varname_and_vartype cmake_varname_and_type varname_var)
  114. set(_vartype_var "${ARGV2}")
  115. string(REPLACE ":" ";" varname_and_vartype ${cmake_varname_and_type})
  116. list(GET varname_and_vartype 0 _varname)
  117. list(GET varname_and_vartype 1 _vartype)
  118. set(${varname_var} ${_varname} PARENT_SCOPE)
  119. if(_vartype_var MATCHES ".+")
  120. set(${_vartype_var} ${_vartype} PARENT_SCOPE)
  121. endif()
  122. endfunction()
  123. function(_sb_list_to_string separator input_list output_string_var)
  124. set(_string "")
  125. cmake_policy(PUSH)
  126. cmake_policy(SET CMP0007 OLD)
  127. # Get list length
  128. list(LENGTH input_list list_length)
  129. # If the list has 0 or 1 element, there is no need to loop over.
  130. if(list_length LESS 2)
  131. set(_string "${input_list}")
  132. else()
  133. math(EXPR last_element_index "${list_length} - 1")
  134. foreach(index RANGE ${last_element_index})
  135. # Get current item_value
  136. list(GET input_list ${index} item_value)
  137. # .. and append to output string
  138. set(_string "${_string}${item_value}")
  139. # Append separator if current element is NOT the last one.
  140. if(NOT index EQUAL last_element_index)
  141. set(_string "${_string}${separator}")
  142. endif()
  143. endforeach()
  144. endif()
  145. set(${output_string_var} ${_string} PARENT_SCOPE)
  146. cmake_policy(POP)
  147. endfunction()
  148. #!
  149. #! _sb_cmakevar_to_cmakearg(<cmake_varname_and_type> <cmake_arg_var> <cmake_arg_type> [<varname_var> [<vartype_var>]])
  150. #!
  151. #! <cmake_varname_and_type> corresponds to variable name and variable type passed as "<varname>:<vartype>"
  152. #!
  153. #! <cmake_arg_var> is a variable name that will be set to "-D<varname>:<vartype>=${<varname>}"
  154. #!
  155. #! <cmake_arg_type> is set to either CMAKE_CACHE or CMAKE_CMD.
  156. #! CMAKE_CACHE means that the generated cmake argument will be passed to
  157. #! ExternalProject_Add as CMAKE_CACHE_ARGS.
  158. #! CMAKE_CMD means that the generated cmake argument will be passed to
  159. #! ExternalProject_Add as CMAKE_ARGS.
  160. #!
  161. #! <varname_var> is an optional variable name that will be set to "<varname>"
  162. #!
  163. #! <vartype_var> is an optional variable name that will be set to "<vartype>"
  164. function(_sb_cmakevar_to_cmakearg cmake_varname_and_type cmake_arg_var cmake_arg_type)
  165. set(_varname_var "${ARGV3}")
  166. set(_vartype_var "${ARGV4}")
  167. # XXX Add check for <cmake_arg_type> value
  168. _sb_extract_varname_and_vartype(${cmake_varname_and_type} _varname _vartype)
  169. set(_var_value "${${_varname}}")
  170. get_property(_value_set_in_cache CACHE ${_varname} PROPERTY VALUE SET)
  171. if(_value_set_in_cache)
  172. get_property(_var_value CACHE ${_varname} PROPERTY VALUE)
  173. endif()
  174. if(cmake_arg_type STREQUAL "CMAKE_CMD")
  175. # Separate list item with <EP_LIST_SEPARATOR>
  176. _sb_list_to_string(${EP_LIST_SEPARATOR} "${_var_value}" _var_value)
  177. endif()
  178. set(${cmake_arg_var} -D${_varname}:${_vartype}=${_var_value} PARENT_SCOPE)
  179. if(_varname_var MATCHES ".+")
  180. set(${_varname_var} ${_varname} PARENT_SCOPE)
  181. endif()
  182. if(_vartype_var MATCHES ".+")
  183. set(${_vartype_var} ${_vartype} PARENT_SCOPE)
  184. endif()
  185. endfunction()
  186. set(_ALL_PROJECT_IDENTIFIER "ALLALLALL")
  187. #!
  188. #! _sb_append_to_cmake_args(
  189. #! VARS <varname1>:<vartype1> [<varname2>:<vartype2> [...]]
  190. #! [PROJECTS <projectname> [<projectname> [...]] | ALL_PROJECTS]
  191. #! [LABELS <label1> [<label2> [...]]]
  192. #! [CMAKE_CMD]
  193. #! )
  194. #!
  195. #! PROJECTS corresponds to a list of <projectname> that will be added using 'ExternalProject_Add' function.
  196. #! If not specified and called within a project file, it defaults to the value of 'SUPERBUILD_TOPLEVEL_PROJECT'
  197. #! Otherwise, it defaults to 'CMAKE_PROJECT_NAME'.
  198. #! If instead 'ALL_PROJECTS' is specified, the variables and labels will be passed to all projects.
  199. #!
  200. #! VARS is an expected list of variables specified as <varname>:<vartype> to pass to <projectname>
  201. #!
  202. #!
  203. #! LABELS is an optional list of label to associate with the variable names specified using 'VARS' and passed to
  204. #! the <projectname> as CMake CACHE args of the form:
  205. #! -D<projectname>_EP_LABEL_<label1>=<varname1>;<varname2>[...]
  206. #! -D<projectname>_EP_LABEL_<label2>=<varname1>;<varname2>[...]
  207. #!
  208. function(_sb_append_to_cmake_args)
  209. set(options ALL_PROJECTS CMAKE_CMD)
  210. set(oneValueArgs)
  211. set(multiValueArgs VARS PROJECTS LABELS)
  212. cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  213. if(NOT _sb_PROJECTS AND NOT _sb_ALL_PROJECTS)
  214. if(SUPERBUILD_TOPLEVEL_PROJECT)
  215. set(_sb_PROJECTS ${SUPERBUILD_TOPLEVEL_PROJECT})
  216. else()
  217. set(_sb_PROJECTS ${CMAKE_PROJECT_NAME})
  218. endif()
  219. endif()
  220. if(_sb_ALL_PROJECTS)
  221. set(_sb_PROJECTS ${_ALL_PROJECT_IDENTIFIER})
  222. endif()
  223. foreach(_sb_PROJECT ${_sb_PROJECTS})
  224. set(_cmake_arg_type "CMAKE_CACHE")
  225. if(_sb_CMAKE_CMD)
  226. set(_cmake_arg_type "CMAKE")
  227. set(optional_arg_CMAKE_CMD "CMAKE_CMD")
  228. endif()
  229. set(_ep_property "${_cmake_arg_type}_ARGS")
  230. set(_ep_varnames "")
  231. foreach(varname_and_vartype ${_sb_VARS})
  232. if(NOT TARGET ${_sb_PROJECT})
  233. set_property(GLOBAL APPEND PROPERTY ${_sb_PROJECT}_EP_${_ep_property} ${varname_and_vartype})
  234. _sb_extract_varname_and_vartype(${varname_and_vartype} _varname)
  235. else()
  236. message(FATAL_ERROR "Function _sb_append_to_cmake_args not allowed because project '${_sb_PROJECT}' already added !")
  237. endif()
  238. list(APPEND _ep_varnames ${_varname})
  239. endforeach()
  240. if(_sb_LABELS)
  241. set_property(GLOBAL APPEND PROPERTY ${_sb_PROJECT}_EP_LABELS ${_sb_LABELS})
  242. foreach(label ${_sb_LABELS})
  243. set_property(GLOBAL APPEND PROPERTY ${_sb_PROJECT}_EP_LABEL_${label} ${_ep_varnames})
  244. endforeach()
  245. endif()
  246. endforeach()
  247. endfunction()
  248. function(_sb_get_external_project_arguments proj varname)
  249. mark_as_superbuild(${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj}:BOOL)
  250. function(_sb_collect_args proj)
  251. # Set list of CMake args associated with each label
  252. get_property(_labels GLOBAL PROPERTY ${proj}_EP_LABELS)
  253. if(_labels)
  254. list(REMOVE_DUPLICATES _labels)
  255. foreach(label ${_labels})
  256. get_property(${proj}_EP_LABEL_${label} GLOBAL PROPERTY ${proj}_EP_LABEL_${label})
  257. list(REMOVE_DUPLICATES ${proj}_EP_LABEL_${label})
  258. _sb_append_to_cmake_args(PROJECTS ${proj}
  259. VARS ${proj}_EP_LABEL_${label}:STRING)
  260. endforeach()
  261. endif()
  262. foreach(cmake_arg_type CMAKE_CMD CMAKE_CACHE)
  263. set(_ep_property "CMAKE_CACHE_ARGS")
  264. if(cmake_arg_type STREQUAL "CMAKE_CMD")
  265. set(_ep_property "CMAKE_ARGS")
  266. endif()
  267. get_property(_args GLOBAL PROPERTY ${proj}_EP_${_ep_property})
  268. foreach(var ${_args})
  269. _sb_cmakevar_to_cmakearg(${var} cmake_arg ${cmake_arg_type})
  270. set_property(GLOBAL APPEND PROPERTY ${proj}_EP_PROPERTY_${_ep_property} ${cmake_arg})
  271. endforeach()
  272. endforeach()
  273. endfunction()
  274. _sb_collect_args(${proj})
  275. _sb_collect_args(${_ALL_PROJECT_IDENTIFIER})
  276. set(_ep_arguments "")
  277. foreach(property CMAKE_ARGS CMAKE_CACHE_ARGS)
  278. get_property(${proj}_EP_PROPERTY_${property} GLOBAL PROPERTY ${proj}_EP_PROPERTY_${property})
  279. get_property(${_ALL_PROJECT_IDENTIFIER}_EP_PROPERTY_${property} GLOBAL PROPERTY ${_ALL_PROJECT_IDENTIFIER}_EP_PROPERTY_${property})
  280. set(_all ${${proj}_EP_PROPERTY_${property}} ${${_ALL_PROJECT_IDENTIFIER}_EP_PROPERTY_${property}})
  281. if(_all)
  282. list(REMOVE_DUPLICATES _all)
  283. list(APPEND _ep_arguments ${property} ${_all})
  284. endif()
  285. endforeach()
  286. list(APPEND _ep_arguments LIST_SEPARATOR ${EP_LIST_SEPARATOR})
  287. list(APPEND _ep_arguments CMAKE_GENERATOR ${EP_CMAKE_GENERATOR})
  288. set(${varname} ${_ep_arguments} PARENT_SCOPE)
  289. endfunction()
  290. function(_sb_update_indent proj)
  291. superbuild_stack_size(SB_PROJECT_STACK _stack_size)
  292. set(_indent "")
  293. if(_stack_size GREATER 0)
  294. foreach(not_used RANGE 1 ${_stack_size})
  295. set(_indent " ${_indent}")
  296. endforeach()
  297. endif()
  298. set_property(GLOBAL PROPERTY SUPERBUILD_${proj}_INDENT ${_indent})
  299. endfunction()
  300. #!
  301. #! ExternalProject_Message(<project_name> <msg> [condition])
  302. #!
  303. function(ExternalProject_Message proj msg)
  304. set(_display 1)
  305. if("${ARGV2}" MATCHES ".+")
  306. set(_display ${ARGN})
  307. endif()
  308. if(${_display})
  309. get_property(_indent GLOBAL PROPERTY SUPERBUILD_${proj}_INDENT)
  310. message(STATUS "SuperBuild - ${_indent}${msg}")
  311. endif()
  312. endfunction()
  313. #!
  314. #! superbuild_stack_content(<stack_name> <output_var>)
  315. #!
  316. #! <stack_name> corresponds to the name of stack.
  317. #!
  318. #! <output_var> is the name of CMake variable that will be set with the content
  319. #! of the stack identified by <stack_name>.
  320. function(superbuild_stack_content stack_name output_var)
  321. get_property(_stack GLOBAL PROPERTY ${stack_name})
  322. set(${output_var} ${_stack} PARENT_SCOPE)
  323. endfunction()
  324. #!
  325. #! superbuild_stack_size(<stack_name> <output_var>)
  326. #!
  327. #! <stack_name> corresponds to the name of stack.
  328. #!
  329. #! <output_var> is the name of CMake variable that will be set with the size
  330. #! of the stack identified by <stack_name>.
  331. function(superbuild_stack_size stack_name output_var)
  332. get_property(_stack GLOBAL PROPERTY ${stack_name})
  333. list(LENGTH _stack _stack_size)
  334. set(${output_var} ${_stack_size} PARENT_SCOPE)
  335. endfunction()
  336. #!
  337. #! superbuild_stack_push(<stack_name> <value>)
  338. #!
  339. #! <stack_name> corresponds to the name of stack.
  340. #!
  341. #! <value> is appended to the stack identified by <stack_name>.
  342. function(superbuild_stack_push stack_name value)
  343. set_property(GLOBAL APPEND PROPERTY ${stack_name} ${value})
  344. endfunction()
  345. #!
  346. #! superbuild_stack_pop(<stack_name> <item_var>)
  347. #!
  348. #! <stack_name> corresponds to the name of stack.
  349. #!
  350. #! <item_var> names a CMake variable that will be set with the item
  351. #! removed from the stack identified by <stack_name>.
  352. function(superbuild_stack_pop stack_name item_var)
  353. get_property(_stack GLOBAL PROPERTY ${stack_name})
  354. list(LENGTH _stack _stack_size)
  355. if(_stack_size GREATER 0)
  356. math(EXPR _index_to_remove "${_stack_size} - 1")
  357. list(GET _stack ${_index_to_remove} _item)
  358. list(REMOVE_AT _stack ${_index_to_remove})
  359. set_property(GLOBAL PROPERTY ${stack_name} ${_stack})
  360. set(${item_var} ${_item} PARENT_SCOPE)
  361. endif()
  362. endfunction()
  363. function(_sb_is_optional proj output_var)
  364. set(_include_project 1)
  365. if(COMMAND superbuild_is_external_project_includable)
  366. superbuild_is_external_project_includable("${proj}" _include_project)
  367. endif()
  368. set(optional 1)
  369. if(_include_project)
  370. set(optional 0)
  371. endif()
  372. set(${output_var} ${optional} PARENT_SCOPE)
  373. endfunction()
  374. #!
  375. #! ExternalProject_Include_Dependencies(<project_name>
  376. #! [PROJECT_VAR <project_var>]
  377. #! [EP_ARGS_VAR <external_project_args_var>]
  378. #! [DEPENDS_VAR <depends_var>]
  379. #! [USE_SYSTEM_VAR <use_system_var>]
  380. #! [SUPERBUILD_VAR <superbuild_var>]
  381. #! )
  382. #!
  383. macro(ExternalProject_Include_Dependencies project_name)
  384. set(options)
  385. set(oneValueArgs PROJECT_VAR DEPENDS_VAR EP_ARGS_VAR USE_SYSTEM_VAR SUPERBUILD_VAR)
  386. set(multiValueArgs)
  387. cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  388. # Sanity checks
  389. if(x${project_name} STREQUAL xPROJECT_VAR
  390. OR x${project_name} STREQUAL xEP_ARGS_VAR
  391. OR x${project_name} STREQUAL xDEPENDS_VAR
  392. OR x${project_name} STREQUAL xUSE_SYSTEM_VAR
  393. OR x${project_name} STREQUAL xSUPERBUILD_VAR
  394. )
  395. message(FATAL_ERROR "Argument <project_name> is missing !")
  396. endif()
  397. if(_sb_UNPARSED_ARGUMENTS)
  398. message(FATAL_ERROR "Invalid arguments: ${_sb_UNPARSED_ARGUMENTS}")
  399. endif()
  400. # Set default for optional PROJECT_VAR parameter
  401. if(NOT _sb_PROJECT_VAR)
  402. set(_sb_PROJECT_VAR proj)
  403. set(${_sb_PROJECT_VAR} ${project_name})
  404. #message("[${project_name}] Setting _sb_PROJECT_VAR with default value '${_sb_PROJECT_VAR}'")
  405. endif()
  406. if(_sb_PROJECT_VAR AND NOT x${project_name} STREQUAL x${${_sb_PROJECT_VAR}})
  407. message(FATAL_ERROR
  408. "Argument <project_name>:${project_name} and PROJECT_VAR:${_sb_PROJECT_VAR}:${${_sb_PROJECT_VAR}} are different !")
  409. endif()
  410. set(_sb_proj ${project_name})
  411. # Skip if project already included
  412. get_property(_is_included GLOBAL PROPERTY SB_${_sb_proj}_FILE_INCLUDED)
  413. if(_is_included)
  414. return()
  415. endif()
  416. # Set default for optional DEPENDS_VAR and EP_ARGS parameters
  417. foreach(param DEPENDS EP_ARGS)
  418. if(NOT _sb_${param}_VAR)
  419. set(_sb_${param}_VAR ${_sb_proj}_${param})
  420. #message("[${project_name}] Setting _sb_${param}_VAR with default value '${_sb_${param}_VAR}'")
  421. endif()
  422. endforeach()
  423. # Set top level project
  424. superbuild_stack_size(SB_PROJECT_STACK _stack_size)
  425. if(_stack_size EQUAL 0)
  426. set(SUPERBUILD_TOPLEVEL_PROJECT ${_sb_proj})
  427. endif()
  428. # Set default for optional USE_SYSTEM_VAR parameter
  429. if(NOT _sb_USE_SYSTEM_VAR)
  430. set(_sb_USE_SYSTEM_VAR ${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${_sb_proj})
  431. #message("[${project_name}] Setting _sb_USE_SYSTEM_VAR with default value '${_sb_USE_SYSTEM_VAR}'")
  432. endif()
  433. # Set default for optional SUPERBUILD_VAR parameter
  434. if(NOT _sb_SUPERBUILD_VAR)
  435. set(_sb_SUPERBUILD_VAR ${SUPERBUILD_TOPLEVEL_PROJECT}_SUPERBUILD)
  436. #message("[${project_name}] Setting _sb_SUPERBUILD_VAR with default value '${_sb_SUPERBUILD_VAR}'")
  437. endif()
  438. # Keeping track of variable name independently of the recursion
  439. if(NOT DEFINED _sb_SB_VAR)
  440. set(_sb_SB_VAR ${_sb_SUPERBUILD_VAR})
  441. #message("[${project_name}] Setting _sb_SB_VAR with default value '${_sb_SB_VAR}'")
  442. endif()
  443. # Set local variables
  444. set(_sb_DEPENDS ${${_sb_DEPENDS_VAR}})
  445. set(_sb_USE_SYSTEM ${${_sb_USE_SYSTEM_VAR}})
  446. _sb_update_indent(${_sb_proj})
  447. # Keep track of the projects
  448. list(APPEND SB_${SUPERBUILD_TOPLEVEL_PROJECT}_POSSIBLE_DEPENDS ${_sb_proj})
  449. # Use system ?
  450. get_property(_use_system_set GLOBAL PROPERTY SB_${_sb_proj}_USE_SYSTEM SET)
  451. if(_use_system_set)
  452. get_property(_sb_USE_SYSTEM GLOBAL PROPERTY SB_${_sb_proj}_USE_SYSTEM)
  453. endif()
  454. # Is this the first run ?
  455. if(${_sb_proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT} AND NOT DEFINED SB_FIRST_PASS)
  456. message(STATUS "SuperBuild - First pass")
  457. set(SB_FIRST_PASS TRUE)
  458. endif()
  459. set(_sb_REQUIRED_DEPENDS)
  460. foreach(dep ${_sb_DEPENDS})
  461. if(NOT ${_sb_proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT})
  462. if(_sb_USE_SYSTEM)
  463. set_property(GLOBAL PROPERTY SB_${dep}_USE_SYSTEM ${_sb_USE_SYSTEM})
  464. #message(${_sb_proj} "Property SB_${dep}_USE_SYSTEM set to [${_sb_USE_SYSTEM_VAR}:${_sb_USE_SYSTEM}]")
  465. endif()
  466. endif()
  467. _sb_is_optional(${dep} _optional)
  468. set_property(GLOBAL PROPERTY SB_${dep}_OPTIONAL ${_optional})
  469. #message(${_sb_proj} "[${_sb_proj}] Property SB_${dep}_OPTIONAL set to ${_optional}")
  470. if(NOT _optional)
  471. list(APPEND _sb_REQUIRED_DEPENDS ${dep})
  472. endif()
  473. endforeach()
  474. # Display dependency of project being processed
  475. if(_sb_REQUIRED_DEPENDS AND SB_SECOND_PASS AND ${_sb_SB_VAR})
  476. set(dependency_str "")
  477. foreach(dep ${_sb_REQUIRED_DEPENDS})
  478. get_property(_is_included GLOBAL PROPERTY SB_${dep}_FILE_INCLUDED)
  479. set(_include_status "")
  480. if(_is_included)
  481. set(_include_status "[INCLUDED]")
  482. endif()
  483. set(dependency_str "${dependency_str}${dep}${_include_status}, ")
  484. endforeach()
  485. ExternalProject_Message(${_sb_proj} "${_sb_proj} => Requires ${dependency_str}")
  486. endif()
  487. # Save variables
  488. set_property(GLOBAL PROPERTY SB_${_sb_proj}_REQUIRED_DEPENDS ${_sb_REQUIRED_DEPENDS})
  489. set_property(GLOBAL PROPERTY SB_${_sb_proj}_DEPENDS ${_sb_DEPENDS})
  490. set_property(GLOBAL PROPERTY SB_${_sb_proj}_DEPENDS_VAR ${_sb_DEPENDS_VAR})
  491. set_property(GLOBAL PROPERTY SB_${_sb_proj}_EP_ARGS_VAR ${_sb_EP_ARGS_VAR})
  492. set_property(GLOBAL PROPERTY SB_${_sb_proj}_USE_SYSTEM ${_sb_USE_SYSTEM})
  493. set_property(GLOBAL PROPERTY SB_${_sb_proj}_USE_SYSTEM_VAR ${_sb_USE_SYSTEM_VAR})
  494. set_property(GLOBAL PROPERTY SB_${_sb_proj}_PROJECT_VAR ${_sb_PROJECT_VAR})
  495. superbuild_stack_push(SB_PROJECT_STACK ${_sb_proj})
  496. # Include dependencies
  497. foreach(dep ${_sb_DEPENDS})
  498. get_property(_included GLOBAL PROPERTY SB_${dep}_FILE_INCLUDED)
  499. if(NOT _included)
  500. # XXX - Refactor - Add a single variable named 'EXTERNAL_PROJECT_DIRS'
  501. if(EXISTS "${EXTERNAL_PROJECT_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake")
  502. include(${EXTERNAL_PROJECT_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake)
  503. elseif(EXISTS "${${dep}_FILEPATH}")
  504. include(${${dep}_FILEPATH})
  505. elseif(EXISTS "${EXTERNAL_PROJECT_ADDITIONAL_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake")
  506. include(${EXTERNAL_PROJECT_ADDITIONAL_DIR}/${EXTERNAL_PEXCLUDEDROJECT_FILE_PREFIX}${dep}.cmake)
  507. else()
  508. message(FATAL_ERROR "Can't find ${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake")
  509. endif()
  510. set_property(GLOBAL PROPERTY SB_${dep}_FILE_INCLUDED 1)
  511. endif()
  512. endforeach()
  513. # Restore variables
  514. superbuild_stack_pop(SB_PROJECT_STACK _sb_proj)
  515. get_property(_sb_PROJECT_VAR GLOBAL PROPERTY SB_${_sb_proj}_PROJECT_VAR)
  516. get_property(_sb_USE_SYSTEM_VAR GLOBAL PROPERTY SB_${_sb_proj}_USE_SYSTEM_VAR)
  517. get_property(_sb_USE_SYSTEM GLOBAL PROPERTY SB_${_sb_proj}_USE_SYSTEM)
  518. get_property(_sb_EP_ARGS_VAR GLOBAL PROPERTY SB_${_sb_proj}_EP_ARGS_VAR)
  519. get_property(_sb_DEPENDS_VAR GLOBAL PROPERTY SB_${_sb_proj}_DEPENDS_VAR)
  520. get_property(_sb_DEPENDS GLOBAL PROPERTY SB_${_sb_proj}_DEPENDS)
  521. get_property(_sb_REQUIRED_DEPENDS GLOBAL PROPERTY SB_${_sb_proj}_REQUIRED_DEPENDS)
  522. # Use system ?
  523. set(_include_type "")
  524. if(_sb_USE_SYSTEM)
  525. set(_include_type " (SYSTEM)")
  526. endif()
  527. get_property(_optional GLOBAL PROPERTY SB_${_sb_proj}_OPTIONAL)
  528. ExternalProject_Message(${_sb_proj} "${_sb_proj}[OK]${_include_type}" SB_SECOND_PASS AND ${_sb_SB_VAR} AND NOT _optional)
  529. if(${_sb_proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT} AND SB_FIRST_PASS)
  530. set(SB_FIRST_PASS FALSE)
  531. ExternalProject_Message(${_sb_proj} "First pass - done")
  532. if(${_sb_SB_VAR})
  533. foreach(possible_proj ${SB_${SUPERBUILD_TOPLEVEL_PROJECT}_POSSIBLE_DEPENDS})
  534. get_property(_optional GLOBAL PROPERTY SB_${possible_proj}_OPTIONAL)
  535. if(_optional)
  536. ExternalProject_Message(${_sb_proj} "${possible_proj}[OPTIONAL]")
  537. endif()
  538. set_property(GLOBAL PROPERTY SB_${possible_proj}_FILE_INCLUDED 0)
  539. endforeach()
  540. set(${_sb_PROJECT_VAR} ${_sb_proj})
  541. set(SB_SECOND_PASS TRUE)
  542. ExternalProject_Include_Dependencies(${_sb_proj}
  543. PROJECT_VAR ${_sb_PROJECT_VAR}
  544. DEPENDS_VAR ${_sb_DEPENDS_VAR}
  545. EP_ARGS_VAR ${_sb_EP_ARGS_VAR}
  546. USE_SYSTEM_VAR _sb_USE_SYSTEM
  547. SUPERBUILD_VAR ${_sb_SB_VAR}
  548. )
  549. set(SB_SECOND_PASS FALSE)
  550. endif()
  551. endif()
  552. if(SB_FIRST_PASS OR _optional)
  553. if(NOT ${_sb_proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT})
  554. return()
  555. endif()
  556. endif()
  557. if(SB_SECOND_PASS)
  558. _sb_get_external_project_arguments(${_sb_proj} ${_sb_EP_ARGS_VAR})
  559. endif()
  560. if(NOT SB_FIRST_PASS AND NOT SB_SECOND_PASS
  561. AND ${_sb_proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT})
  562. #ExternalProject_Message(${_sb_proj} "Clean up")
  563. unset(_sb_SB_VAR)
  564. unset(SB_FIRST_PASS)
  565. unset(SB_SECOND_PASS)
  566. endif()
  567. # Set public variables
  568. set(${_sb_PROJECT_VAR} ${_sb_proj})
  569. set(${_sb_DEPENDS_VAR} ${_sb_REQUIRED_DEPENDS})
  570. set(${_sb_USE_SYSTEM_VAR} ${_sb_USE_SYSTEM})
  571. #message("[${_sb_proj}] #################################")
  572. #message("[${_sb_proj}] Setting ${_sb_PROJECT_VAR}:${_sb_proj}")
  573. #message("[${_sb_proj}] Setting ${_sb_EP_ARGS_VAR}:${${_sb_EP_ARGS_VAR}}")
  574. #message("[${_sb_proj}] Setting ${_sb_DEPENDS_VAR}:${${_sb_DEPENDS_VAR}}")
  575. #message("[${_sb_proj}] Setting ${_sb_USE_SYSTEM_VAR}:${_sb_USE_SYSTEM}")
  576. endmacro()
  577. #!
  578. #! ExternalProject_Add_Empty(<project_name>
  579. #! DEPENDS <depends>
  580. #! )
  581. #!
  582. macro(ExternalProject_Add_Empty project_name)
  583. set(options)
  584. set(oneValueArgs)
  585. set(multiValueArgs DEPENDS)
  586. cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  587. # Sanity checks
  588. if(x${project_name} STREQUAL xDEPENDS)
  589. message(FATAL_ERROR "Argument <project_name> is missing !")
  590. endif()
  591. if(_sb_UNPARSED_ARGUMENTS)
  592. message(FATAL_ERROR "Invalid arguments: ${_sb_UNPARSED_ARGUMENTS}")
  593. endif()
  594. ExternalProject_Add(${project_name}
  595. SOURCE_DIR ${CMAKE_BINARY_DIR}/${project_name}
  596. BINARY_DIR ${project_name}-build
  597. DOWNLOAD_COMMAND ""
  598. CONFIGURE_COMMAND ""
  599. BUILD_COMMAND ""
  600. INSTALL_COMMAND ""
  601. DEPENDS ${_sb_DEPENDS}
  602. )
  603. endmacro()