ctkMacroCheckExternalProjectDependency.cmake 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. #.rst:
  2. # ExternalProjectDependency
  3. # -------------------------
  4. #
  5. # .. only:: html
  6. #
  7. # .. contents::
  8. ###########################################################################
  9. #
  10. # Library: CTK
  11. #
  12. # Copyright (c) Kitware Inc.
  13. #
  14. # Licensed under the Apache License, Version 2.0 (the "License");
  15. # you may not use this file except in compliance with the License.
  16. # You may obtain a copy of the License at
  17. #
  18. # http://www.apache.org/licenses/LICENSE-2.0.txt
  19. #
  20. # Unless required by applicable law or agreed to in writing, software
  21. # distributed under the License is distributed on an "AS IS" BASIS,
  22. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23. # See the License for the specific language governing permissions and
  24. # limitations under the License.
  25. #
  26. ###########################################################################
  27. include(CMakeParseArguments)
  28. if(NOT DEFINED EP_LIST_SEPARATOR)
  29. set(EP_LIST_SEPARATOR "^^")
  30. endif()
  31. #.rst:
  32. # Global Variables
  33. # ^^^^^^^^^^^^^^^^
  34. #.rst:
  35. # .. cmake:variable:: EXTERNAL_PROJECT_DIR
  36. #
  37. # This variable describes the directory in which external project files
  38. # matching ``<EXTERNAL_PROJECT_FILE_PREFIX><projectname>.cmake`` expression are globbed.
  39. #
  40. if(NOT EXISTS "${EXTERNAL_PROJECT_DIR}")
  41. set(EXTERNAL_PROJECT_DIR ${CMAKE_SOURCE_DIR}/SuperBuild)
  42. endif()
  43. #.rst:
  44. # .. cmake:variable:: EXTERNAL_PROJECT_ADDITIONAL_DIR
  45. #
  46. # If set, this variable represents an other directory in which external project files
  47. # are searched for if not already found in ``EXTERNAL_PROJECT_DIR``.
  48. #.rst:
  49. # .. cmake:variable:: EXTERNAL_PROJECT_FILE_PREFIX
  50. #
  51. # This variable describes the prefix of the external project files looked up in
  52. # ``EXTERNAL_PROJECT_DIR``. It defaults to ``External_``.
  53. #
  54. if(NOT DEFINED EXTERNAL_PROJECT_FILE_PREFIX)
  55. set(EXTERNAL_PROJECT_FILE_PREFIX "External_")
  56. endif()
  57. #.rst:
  58. # .. cmake:variable:: SUPERBUILD_TOPLEVEL_PROJECT
  59. #
  60. # This variable can be set to explicitly identify the name of the top-level project.
  61. # If not set, it default to the value of ``CMAKE_PROJECT_NAME``.
  62. # Compute -G arg for configuring external projects with the same CMake generator:
  63. if(CMAKE_EXTRA_GENERATOR)
  64. set(EP_CMAKE_GENERATOR "${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}")
  65. else()
  66. set(EP_CMAKE_GENERATOR "${CMAKE_GENERATOR}")
  67. endif()
  68. set(EP_CMAKE_GENERATOR_PLATFORM "${CMAKE_GENERATOR_PLATFORM}")
  69. set(EP_CMAKE_GENERATOR_TOOLSET "${CMAKE_GENERATOR_TOOLSET}")
  70. #.rst:
  71. # Functions
  72. # ^^^^^^^^^
  73. #.rst:
  74. # .. cmake:function:: mark_as_superbuild
  75. #
  76. # .. code-block:: cmake
  77. #
  78. # mark_as_superbuild(<varname1>[:<vartype1>] [<varname2>[:<vartype2>] [...]])
  79. #
  80. # .. code-block:: cmake
  81. #
  82. # mark_as_superbuild(
  83. # VARS <varname1>[:<vartype1>] [<varname2>[:<vartype2>] [...]]
  84. # [PROJECTS <projectname> [<projectname> [...]] | ALL_PROJECTS]
  85. # [LABELS <label1> [<label2> [...]]]
  86. # )
  87. #
  88. # .. code-block:: cmake
  89. #
  90. # PROJECTS corresponds to a list of <projectname> that will be added using 'ExternalProject_Add' function.
  91. # If not specified and called within a project file, it defaults to the value of 'SUPERBUILD_TOPLEVEL_PROJECT'
  92. # Otherwise, it defaults to 'CMAKE_PROJECT_NAME'.
  93. # If instead 'ALL_PROJECTS' is specified, the variables and labels will be passed to all projects.
  94. #
  95. # VARS is an expected list of variables specified as <varname>:<vartype> to pass to <projectname>
  96. #
  97. #
  98. # LABELS is an optional list of label to associate with the variable names specified using 'VARS' and passed to
  99. # the <projectname> as CMake CACHE args of the form:
  100. # -D<projectname>_EP_LABEL_<label1>=<varname1>;<varname2>[...]
  101. # -D<projectname>_EP_LABEL_<label2>=<varname1>;<varname2>[...]
  102. #
  103. function(mark_as_superbuild)
  104. set(options ALL_PROJECTS CMAKE_CMD)
  105. set(oneValueArgs)
  106. set(multiValueArgs VARS PROJECTS LABELS)
  107. cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  108. set(_vars ${_sb_UNPARSED_ARGUMENTS})
  109. set(_named_parameters_expected 0)
  110. if(_sb_PROJECTS OR _sb_ALL_PROJECTS OR _sb_LABELS OR _sb_VARS)
  111. set(_named_parameters_expected 1)
  112. set(_vars ${_sb_VARS})
  113. endif()
  114. if(_named_parameters_expected AND _sb_UNPARSED_ARGUMENTS)
  115. message(FATAL_ERROR "Arguments '${_sb_UNPARSED_ARGUMENTS}' should be associated with VARS parameter !")
  116. endif()
  117. if(_sb_PROJECTS AND _sb_ALL_PROJECTS)
  118. message(FATAL_ERROR "Arguments 'PROJECTS' and 'ALL_PROJECTS' are mutually exclusive !")
  119. endif()
  120. foreach(var ${_vars})
  121. set(_type_specified 0)
  122. if(var MATCHES ":")
  123. set(_type_specified 1)
  124. endif()
  125. # XXX Display warning with variable type is also specified for cache variable.
  126. set(_var ${var})
  127. if(NOT _type_specified)
  128. get_property(_type_set_in_cache CACHE ${_var} PROPERTY TYPE SET)
  129. set(_var_name ${_var})
  130. set(_var_type "STRING")
  131. if(_type_set_in_cache)
  132. get_property(_var_type CACHE ${_var_name} PROPERTY TYPE)
  133. endif()
  134. set(_var ${_var_name}:${_var_type})
  135. endif()
  136. list(APPEND _vars_with_type ${_var})
  137. endforeach()
  138. if(_sb_ALL_PROJECTS)
  139. set(optional_arg_ALL_PROJECTS "ALL_PROJECTS")
  140. else()
  141. set(optional_arg_ALL_PROJECTS PROJECTS ${_sb_PROJECTS})
  142. endif()
  143. _sb_append_to_cmake_args(
  144. VARS ${_vars_with_type} LABELS ${_sb_LABELS} ${optional_arg_ALL_PROJECTS})
  145. endfunction()
  146. #
  147. # _sb_extract_varname_and_vartype(<cmake_varname_and_type> <varname_var> [<vartype_var>])
  148. #
  149. # <cmake_varname_and_type> corresponds to variable name and variable type passed as "<varname>:<vartype>"
  150. #
  151. # <varname_var> will be set to "<varname>"
  152. #
  153. # <vartype_var> is an optional variable name that will be set to "<vartype>"
  154. #
  155. function(_sb_extract_varname_and_vartype cmake_varname_and_type varname_var)
  156. set(_vartype_var "${ARGV2}")
  157. string(REPLACE ":" ";" varname_and_vartype ${cmake_varname_and_type})
  158. list(GET varname_and_vartype 0 _varname)
  159. list(GET varname_and_vartype 1 _vartype)
  160. set(${varname_var} ${_varname} PARENT_SCOPE)
  161. if(_vartype_var MATCHES ".+")
  162. set(${_vartype_var} ${_vartype} PARENT_SCOPE)
  163. endif()
  164. endfunction()
  165. function(_sb_list_to_string separator input_list output_string_var)
  166. set(_string "")
  167. # Get list length
  168. list(LENGTH input_list list_length)
  169. # If the list has 0 or 1 element, there is no need to loop over.
  170. if(list_length LESS 2)
  171. set(_string "${input_list}")
  172. else()
  173. math(EXPR last_element_index "${list_length} - 1")
  174. foreach(index RANGE ${last_element_index})
  175. # Get current item_value
  176. list(GET input_list ${index} item_value)
  177. if(NOT item_value STREQUAL "")
  178. # .. and append non-empty value to output string
  179. set(_string "${_string}${item_value}")
  180. # Append separator if current element is NOT the last one.
  181. if(NOT index EQUAL last_element_index)
  182. set(_string "${_string}${separator}")
  183. endif()
  184. endif()
  185. endforeach()
  186. endif()
  187. set(${output_string_var} ${_string} PARENT_SCOPE)
  188. endfunction()
  189. #
  190. # _sb_cmakevar_to_cmakearg(<cmake_varname_and_type> <cmake_arg_var> <has_cfg_intdir_var> [<varname_var> [<vartype_var>]])
  191. #
  192. # <cmake_varname_and_type> corresponds to variable name and variable type passed as "<varname>:<vartype>"
  193. #
  194. # <cmake_arg_var> is a variable name that will be set to "-D<varname>:<vartype>=${<varname>}"
  195. #
  196. # <has_int_dir_var> is set to either TRUE or FALSE.
  197. # FALSE means that the value does NOT reference ${CMAKE_CFG_INTDIR} and
  198. # the generated cmake argument should be passed to ExternalProject_Add as CMAKE_CACHE_ARGS.
  199. # TRUEmeans that the value does reference ${CMAKE_CFG_INTDIR} and
  200. # the generated cmake argument should be passed to ExternalProject_Add as CMAKE_ARGS.
  201. #
  202. # <varname_var> is an optional variable name that will be set to "<varname>"
  203. #
  204. # <vartype_var> is an optional variable name that will be set to "<vartype>"
  205. #
  206. function(_sb_cmakevar_to_cmakearg cmake_varname_and_type cmake_arg_var has_cfg_intdir_var)
  207. set(_varname_var "${ARGV3}")
  208. set(_vartype_var "${ARGV4}")
  209. _sb_extract_varname_and_vartype(${cmake_varname_and_type} _varname _vartype)
  210. set(_var_value "${${_varname}}")
  211. get_property(_value_set_in_cache CACHE ${_varname} PROPERTY VALUE SET)
  212. if(_value_set_in_cache)
  213. get_property(_var_value CACHE ${_varname} PROPERTY VALUE)
  214. endif()
  215. set(_has_cfg_intdir FALSE)
  216. if(CMAKE_CONFIGURATION_TYPES)
  217. string(FIND "${_var_value}" ${CMAKE_CFG_INTDIR} _index)
  218. if(NOT _index EQUAL -1)
  219. # Separate list item with <EP_LIST_SEPARATOR>
  220. _sb_list_to_string(${EP_LIST_SEPARATOR} "${_var_value}" _var_value)
  221. set(_has_cfg_intdir TRUE)
  222. endif()
  223. endif()
  224. if(NOT _has_cfg_intdir)
  225. string(REPLACE "\"" "\\\"" _var_value "${_var_value}")
  226. endif()
  227. set(${cmake_arg_var} -D${_varname}:${_vartype}=${_var_value} PARENT_SCOPE)
  228. set(${has_cfg_intdir_var} ${_has_cfg_intdir} PARENT_SCOPE)
  229. if(_varname_var MATCHES ".+")
  230. set(${_varname_var} ${_varname} PARENT_SCOPE)
  231. endif()
  232. if(_vartype_var MATCHES ".+")
  233. set(${_vartype_var} ${_vartype} PARENT_SCOPE)
  234. endif()
  235. endfunction()
  236. set(_ALL_PROJECT_IDENTIFIER "ALLALLALL")
  237. #
  238. # _sb_append_to_cmake_args(
  239. # [VARS <varname1>:<vartype1> [<varname2>:<vartype2> [...]]]
  240. # [PROJECTS <projectname> [<projectname> [...]] | ALL_PROJECTS]
  241. # [LABELS <label1> [<label2> [...]]]
  242. # )
  243. #
  244. # PROJECTS corresponds to a list of <projectname> that will be added using 'ExternalProject_Add' function.
  245. # If not specified and called within a project file, it defaults to the value of 'SUPERBUILD_TOPLEVEL_PROJECT'
  246. # Otherwise, it defaults to 'CMAKE_PROJECT_NAME'.
  247. # If instead 'ALL_PROJECTS' is specified, the variables and labels will be passed to all projects.
  248. #
  249. # VARS is an expected list of variables specified as <varname>:<vartype> to pass to <projectname>
  250. #
  251. #
  252. # LABELS is an optional list of label to associate with the variable names specified using 'VARS' and passed to
  253. # the <projectname> as CMake CACHE args of the form:
  254. # -D<projectname>_EP_LABEL_<label1>=<varname1>;<varname2>[...]
  255. # -D<projectname>_EP_LABEL_<label2>=<varname1>;<varname2>[...]
  256. #
  257. function(_sb_append_to_cmake_args)
  258. set(options ALL_PROJECTS)
  259. set(oneValueArgs)
  260. set(multiValueArgs VARS PROJECTS LABELS)
  261. cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  262. if(NOT _sb_PROJECTS AND NOT _sb_ALL_PROJECTS)
  263. if(SUPERBUILD_TOPLEVEL_PROJECT)
  264. set(_sb_PROJECTS ${SUPERBUILD_TOPLEVEL_PROJECT})
  265. else()
  266. set(_sb_PROJECTS ${CMAKE_PROJECT_NAME})
  267. endif()
  268. endif()
  269. if(_sb_ALL_PROJECTS)
  270. set(_sb_PROJECTS ${_ALL_PROJECT_IDENTIFIER})
  271. endif()
  272. foreach(_sb_PROJECT ${_sb_PROJECTS})
  273. set(_ep_varnames "")
  274. foreach(varname_and_vartype ${_sb_VARS})
  275. if(NOT TARGET ${_sb_PROJECT})
  276. set_property(GLOBAL APPEND PROPERTY ${_sb_PROJECT}_EP_CMAKE_ARGS ${varname_and_vartype})
  277. _sb_extract_varname_and_vartype(${varname_and_vartype} _varname)
  278. else()
  279. message(FATAL_ERROR "Function _sb_append_to_cmake_args not allowed because project '${_sb_PROJECT}' already added !")
  280. endif()
  281. list(APPEND _ep_varnames ${_varname})
  282. endforeach()
  283. if(_sb_LABELS)
  284. set_property(GLOBAL APPEND PROPERTY ${_sb_PROJECT}_EP_LABELS ${_sb_LABELS})
  285. foreach(label ${_sb_LABELS})
  286. set_property(GLOBAL APPEND PROPERTY ${_sb_PROJECT}_EP_LABEL_${label} ${_ep_varnames})
  287. endforeach()
  288. endif()
  289. endforeach()
  290. endfunction()
  291. #.rst:
  292. # .. cmake:function:: ExternalProject_DeclareLabels
  293. #
  294. # .. code-block:: cmake
  295. #
  296. # ExternalProject_DeclareLabels(
  297. # [PROJECTS <projectname> [<projectname> [...]] | ALL_PROJECTS]
  298. # LABELS <label1> [<label2> [...]]
  299. # )
  300. #
  301. # .. code-block:: cmake
  302. #
  303. # PROJECTS corresponds to a list of <projectname> that will be added using 'ExternalProject_Add' function.
  304. # If not specified and called within a project file, it defaults to the value of 'SUPERBUILD_TOPLEVEL_PROJECT'
  305. # Otherwise, it defaults to 'CMAKE_PROJECT_NAME'.
  306. # If instead 'ALL_PROJECTS' is specified, the variables and labels will be passed to all projects.
  307. #
  308. # LABELS is a list of label to pass to the <projectname> as CMake CACHE args of the
  309. # form -D<projectname>_EP_LABEL_<label>= unless specific variables
  310. # have been associated with the labels using mark_as_superbuild.
  311. #
  312. function(ExternalProject_DeclareLabels)
  313. set(options ALL_PROJECTS)
  314. set(oneValueArgs)
  315. set(multiValueArgs PROJECTS LABELS)
  316. cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  317. if(_sb_PROJECTS AND _sb_ALL_PROJECTS)
  318. message(FATAL_ERROR "Arguments 'PROJECTS' and 'ALL_PROJECTS' are mutually exclusive !")
  319. endif()
  320. if(_sb_ALL_PROJECTS)
  321. set(optional_arg_ALL_PROJECTS "ALL_PROJECTS")
  322. else()
  323. set(optional_arg_ALL_PROJECTS PROJECTS ${_sb_PROJECTS})
  324. endif()
  325. _sb_append_to_cmake_args(
  326. LABELS ${_sb_LABELS} ${optional_arg_ALL_PROJECTS})
  327. endfunction()
  328. function(_sb_get_external_project_arguments proj varname)
  329. mark_as_superbuild(${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${proj}:BOOL)
  330. function(_sb_collect_args proj)
  331. # Set list of CMake args associated with each label
  332. get_property(_labels GLOBAL PROPERTY ${proj}_EP_LABELS)
  333. if(_labels)
  334. list(REMOVE_DUPLICATES _labels)
  335. foreach(label ${_labels})
  336. get_property(${proj}_EP_LABEL_${label} GLOBAL PROPERTY ${proj}_EP_LABEL_${label})
  337. if(${proj}_EP_LABEL_${label})
  338. list(REMOVE_DUPLICATES ${proj}_EP_LABEL_${label})
  339. endif()
  340. _sb_append_to_cmake_args(PROJECTS ${proj}
  341. VARS ${proj}_EP_LABEL_${label}:STRING)
  342. endforeach()
  343. endif()
  344. get_property(_args GLOBAL PROPERTY ${proj}_EP_CMAKE_ARGS)
  345. foreach(var ${_args})
  346. _sb_cmakevar_to_cmakearg(${var} cmake_arg _has_cfg_intdir)
  347. set(_ep_property "CMAKE_CACHE_ARGS")
  348. if(_has_cfg_intdir)
  349. set(_ep_property "CMAKE_ARGS")
  350. endif()
  351. set_property(GLOBAL APPEND PROPERTY ${proj}_EP_PROPERTY_${_ep_property} ${cmake_arg})
  352. endforeach()
  353. endfunction()
  354. _sb_collect_args(${proj})
  355. _sb_collect_args(${_ALL_PROJECT_IDENTIFIER})
  356. set(_ep_arguments "")
  357. # Automatically propagate CMake options
  358. foreach(_cmake_option IN ITEMS
  359. CMAKE_EXPORT_COMPILE_COMMANDS
  360. )
  361. if(DEFINED ${_cmake_option})
  362. list(APPEND _ep_arguments CMAKE_CACHE_ARGS
  363. -D${_cmake_option}:BOOL=${${_cmake_option}}
  364. )
  365. endif()
  366. endforeach()
  367. foreach(property CMAKE_ARGS CMAKE_CACHE_ARGS)
  368. get_property(${proj}_EP_PROPERTY_${property} GLOBAL PROPERTY ${proj}_EP_PROPERTY_${property})
  369. get_property(${_ALL_PROJECT_IDENTIFIER}_EP_PROPERTY_${property} GLOBAL PROPERTY ${_ALL_PROJECT_IDENTIFIER}_EP_PROPERTY_${property})
  370. set(_all ${${proj}_EP_PROPERTY_${property}} ${${_ALL_PROJECT_IDENTIFIER}_EP_PROPERTY_${property}})
  371. if(_all)
  372. list(APPEND _ep_arguments ${property} ${_all})
  373. endif()
  374. endforeach()
  375. list(APPEND _ep_arguments LIST_SEPARATOR ${EP_LIST_SEPARATOR})
  376. list(APPEND _ep_arguments CMAKE_GENERATOR ${_sb_CMAKE_GENERATOR})
  377. if(CMAKE_VERSION VERSION_GREATER "3.0")
  378. list(APPEND _ep_arguments CMAKE_GENERATOR_PLATFORM ${_sb_CMAKE_GENERATOR_PLATFORM})
  379. endif()
  380. list(APPEND _ep_arguments CMAKE_GENERATOR_TOOLSET ${_sb_CMAKE_GENERATOR_TOOLSET})
  381. if(CMAKE_VERSION VERSION_EQUAL "3.4" OR CMAKE_VERSION VERSION_GREATER "3.4")
  382. # USES_TERMINAL_* options were introduced in CMake 3.4
  383. foreach(step IN ITEMS DOWNLOAD UPDATE CONFIGURE BUILD TEST INSTALL)
  384. list(APPEND _ep_arguments
  385. USES_TERMINAL_${step}
  386. )
  387. endforeach()
  388. endif()
  389. set(${varname} ${_ep_arguments} PARENT_SCOPE)
  390. endfunction()
  391. function(_sb_update_indent proj)
  392. superbuild_stack_size(SB_PROJECT_STACK _stack_size)
  393. set(_indent "")
  394. if(_stack_size GREATER 0)
  395. foreach(not_used RANGE 1 ${_stack_size})
  396. set(_indent " ${_indent}")
  397. endforeach()
  398. endif()
  399. set_property(GLOBAL PROPERTY SUPERBUILD_${proj}_INDENT ${_indent})
  400. endfunction()
  401. #.rst:
  402. # .. cmake:function:: ExternalProject_Message
  403. #
  404. # .. code-block:: cmake
  405. #
  406. # ExternalProject_Message(<project_name> <msg> [condition])
  407. #
  408. function(ExternalProject_Message proj msg)
  409. set(_display 1)
  410. if(NOT "x${ARGV2}" STREQUAL "x")
  411. set(_display ${ARGN})
  412. endif()
  413. if(${_display})
  414. get_property(_indent GLOBAL PROPERTY SUPERBUILD_${proj}_INDENT)
  415. message(STATUS "SuperBuild - ${_indent}${msg}")
  416. endif()
  417. endfunction()
  418. #
  419. # superbuild_stack_content(<stack_name> <output_var>)
  420. #
  421. # <stack_name> corresponds to the name of stack.
  422. #
  423. # <output_var> is the name of CMake variable that will be set with the content
  424. # of the stack identified by <stack_name>.
  425. #
  426. function(superbuild_stack_content stack_name output_var)
  427. get_property(_stack GLOBAL PROPERTY ${stack_name})
  428. set(${output_var} ${_stack} PARENT_SCOPE)
  429. endfunction()
  430. #
  431. # superbuild_stack_size(<stack_name> <output_var>)
  432. #
  433. # <stack_name> corresponds to the name of stack.
  434. #
  435. # <output_var> is the name of CMake variable that will be set with the size
  436. # of the stack identified by <stack_name>.
  437. #
  438. function(superbuild_stack_size stack_name output_var)
  439. get_property(_stack GLOBAL PROPERTY ${stack_name})
  440. list(LENGTH _stack _stack_size)
  441. set(${output_var} ${_stack_size} PARENT_SCOPE)
  442. endfunction()
  443. #
  444. # superbuild_stack_push(<stack_name> <value>)
  445. #
  446. # <stack_name> corresponds to the name of stack.
  447. #
  448. # <value> is appended to the stack identified by <stack_name>.
  449. #
  450. function(superbuild_stack_push stack_name value)
  451. set_property(GLOBAL APPEND PROPERTY ${stack_name} ${value})
  452. endfunction()
  453. #
  454. # superbuild_stack_pop(<stack_name> <item_var>)
  455. #
  456. # <stack_name> corresponds to the name of stack.
  457. #
  458. # <item_var> names a CMake variable that will be set with the item
  459. # removed from the stack identified by <stack_name>
  460. #
  461. function(superbuild_stack_pop stack_name item_var)
  462. get_property(_stack GLOBAL PROPERTY ${stack_name})
  463. list(LENGTH _stack _stack_size)
  464. if(_stack_size GREATER 0)
  465. math(EXPR _index_to_remove "${_stack_size} - 1")
  466. list(GET _stack ${_index_to_remove} _item)
  467. list(REMOVE_AT _stack ${_index_to_remove})
  468. set_property(GLOBAL PROPERTY ${stack_name} ${_stack})
  469. set(${item_var} ${_item} PARENT_SCOPE)
  470. endif()
  471. endfunction()
  472. function(_sb_is_optional proj output_var)
  473. set(_include_project 1)
  474. if(COMMAND superbuild_is_external_project_includable)
  475. superbuild_is_external_project_includable("${proj}" _include_project)
  476. endif()
  477. set(optional 1)
  478. if(_include_project)
  479. set(optional 0)
  480. endif()
  481. set(${output_var} ${optional} PARENT_SCOPE)
  482. endfunction()
  483. #.rst:
  484. # .. cmake:function:: ExternalProject_Include_Dependencies
  485. #
  486. # .. code-block:: cmake
  487. #
  488. # ExternalProject_Include_Dependencies(<project_name>
  489. # [PROJECT_VAR <project_var>]
  490. # [EP_ARGS_VAR <external_project_args_var>]
  491. # [DEPENDS_VAR <depends_var>]
  492. # [USE_SYSTEM_VAR <use_system_var>]
  493. # [SUPERBUILD_VAR <superbuild_var>]
  494. # [CMAKE_GENERATOR <cmake_generator>]
  495. # [CMAKE_GENERATOR_PLATFORM <cmake_generator_platform>]
  496. # [CMAKE_GENERATOR_TOOLSET <cmake_generator_toolset>]
  497. # )
  498. #
  499. #
  500. # .. code-block:: cmake
  501. #
  502. # PROJECT_VAR Name of the variable containing the name of the included project.
  503. # By default, it is `proj` and it is set to `<project_name>`.
  504. #
  505. # EP_ARGS_VAR Name of the variable listing arguments to pass to ExternalProject.
  506. # If not specified, variable name default to `<project_name>_EP_ARGS`.
  507. #
  508. # DEPENDS_VAR Name of the variable containing the dependency of the included project.
  509. # By default, it is `<project_name>_DEPENDS`.
  510. #
  511. #
  512. # USE_SYSTEM_VAR Name of the variable indicating if the system version of <project_name>
  513. # should be looked up. Lookup of the project is left to the developer implementing
  514. # the external project file.
  515. # By default, it is `<SUPERBUILD_TOPLEVEL_PROJECT>_USE_SYSTEM_<project_name>`.
  516. #
  517. # SUPERBUILD_VAR Name of the variable indicating if the top-level or inner project is being built.
  518. # By default, it is `<SUPERBUILD_TOPLEVEL_PROJECT>_SUPERBUILD`.
  519. #
  520. #
  521. # CMAKE_GENERATOR
  522. # CMAKE_GENERATOR_PLATFORM
  523. # CMAKE_GENERATOR_TOOLSET These three options allow to overwrite the values set in the top-level project that
  524. # would otherwise automatically be propagated to dependent projects.
  525. #
  526. macro(ExternalProject_Include_Dependencies project_name)
  527. set(options)
  528. set(oneValueArgs PROJECT_VAR DEPENDS_VAR EP_ARGS_VAR USE_SYSTEM_VAR SUPERBUILD_VAR
  529. CMAKE_GENERATOR
  530. CMAKE_GENERATOR_PLATFORM
  531. CMAKE_GENERATOR_TOOLSET
  532. )
  533. set(multiValueArgs)
  534. cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  535. # Sanity checks
  536. if(x${project_name} STREQUAL xPROJECT_VAR
  537. OR x${project_name} STREQUAL xEP_ARGS_VAR
  538. OR x${project_name} STREQUAL xDEPENDS_VAR
  539. OR x${project_name} STREQUAL xUSE_SYSTEM_VAR
  540. OR x${project_name} STREQUAL xSUPERBUILD_VAR
  541. OR x${project_name} STREQUAL xCMAKE_GENERATOR
  542. OR x${project_name} STREQUAL xCMAKE_GENERATOR_PLATFORM
  543. OR x${project_name} STREQUAL xCMAKE_GENERATOR_TOOLSET
  544. )
  545. message(FATAL_ERROR "Argument <project_name> is missing !")
  546. endif()
  547. if(_sb_UNPARSED_ARGUMENTS)
  548. message(FATAL_ERROR "Invalid arguments: ${_sb_UNPARSED_ARGUMENTS}")
  549. endif()
  550. # Set default for optional PROJECT_VAR parameter
  551. if(NOT _sb_PROJECT_VAR)
  552. set(_sb_PROJECT_VAR proj)
  553. set(${_sb_PROJECT_VAR} ${project_name})
  554. #message("[${project_name}] Setting _sb_PROJECT_VAR with default value '${_sb_PROJECT_VAR}'")
  555. endif()
  556. if(_sb_PROJECT_VAR AND NOT x${project_name} STREQUAL x${${_sb_PROJECT_VAR}})
  557. message(FATAL_ERROR
  558. "Argument <project_name>:${project_name} and PROJECT_VAR:${_sb_PROJECT_VAR}:${${_sb_PROJECT_VAR}} are different !")
  559. endif()
  560. set(_sb_proj ${project_name})
  561. # Skip if project already included
  562. get_property(_is_included GLOBAL PROPERTY SB_${_sb_proj}_FILE_INCLUDED)
  563. if(_is_included)
  564. return()
  565. endif()
  566. # Set default for optional DEPENDS_VAR and EP_ARGS parameters
  567. foreach(param DEPENDS EP_ARGS)
  568. if(NOT _sb_${param}_VAR)
  569. set(_sb_${param}_VAR ${_sb_proj}_${param})
  570. #message("[${project_name}] Setting _sb_${param}_VAR with default value '${_sb_${param}_VAR}'")
  571. endif()
  572. endforeach()
  573. # Set top level project
  574. superbuild_stack_size(SB_PROJECT_STACK _stack_size)
  575. if(_stack_size EQUAL 0)
  576. set(SUPERBUILD_TOPLEVEL_PROJECT ${_sb_proj})
  577. endif()
  578. # Set default for optional USE_SYSTEM_VAR parameter
  579. if(NOT _sb_USE_SYSTEM_VAR)
  580. set(_sb_USE_SYSTEM_VAR ${SUPERBUILD_TOPLEVEL_PROJECT}_USE_SYSTEM_${_sb_proj})
  581. #message("[${project_name}] Setting _sb_USE_SYSTEM_VAR with default value '${_sb_USE_SYSTEM_VAR}'")
  582. endif()
  583. # Set default for optional SUPERBUILD_VAR parameter
  584. if(NOT _sb_SUPERBUILD_VAR)
  585. set(_sb_SUPERBUILD_VAR ${SUPERBUILD_TOPLEVEL_PROJECT}_SUPERBUILD)
  586. #message("[${project_name}] Setting _sb_SUPERBUILD_VAR with default value '${_sb_SUPERBUILD_VAR}'")
  587. endif()
  588. # Set default for optional CMAKE_GENERATOR_* parameters
  589. foreach(varname IN ITEMS
  590. "CMAKE_GENERATOR"
  591. "CMAKE_GENERATOR_PLATFORM"
  592. "CMAKE_GENERATOR_TOOLSET"
  593. )
  594. if(NOT _sb_${varname})
  595. set(_sb_${varname} ${EP_${varname}})
  596. #message("[${project_name}] Setting _sb_${varname} with default value '${_sb_${varname}}'")
  597. else()
  598. #message("[${project_name}] Setting _sb_${varname} to value '${_sb_${varname}}'")
  599. endif()
  600. endforeach()
  601. # Keeping track of variable name independently of the recursion
  602. if(NOT DEFINED _sb_SB_VAR)
  603. set(_sb_SB_VAR ${_sb_SUPERBUILD_VAR})
  604. #message("[${project_name}] Setting _sb_SB_VAR with default value '${_sb_SB_VAR}'")
  605. endif()
  606. # Set local variables
  607. set(_sb_DEPENDS ${${_sb_DEPENDS_VAR}})
  608. set(_sb_USE_SYSTEM ${${_sb_USE_SYSTEM_VAR}})
  609. _sb_update_indent(${_sb_proj})
  610. # Keep track of the projects
  611. list(APPEND SB_${SUPERBUILD_TOPLEVEL_PROJECT}_POSSIBLE_DEPENDS ${_sb_proj})
  612. # Use system ?
  613. get_property(_use_system_set GLOBAL PROPERTY SB_${_sb_proj}_USE_SYSTEM SET)
  614. if(_use_system_set)
  615. get_property(_sb_USE_SYSTEM GLOBAL PROPERTY SB_${_sb_proj}_USE_SYSTEM)
  616. endif()
  617. # Is this the first run ?
  618. if(${_sb_proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT} AND NOT DEFINED SB_FIRST_PASS)
  619. message(STATUS "SuperBuild - First pass")
  620. set(SB_FIRST_PASS TRUE)
  621. endif()
  622. set(_sb_REQUIRED_DEPENDS)
  623. foreach(dep ${_sb_DEPENDS})
  624. if(NOT ${_sb_proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT})
  625. # Set "use system" variable if it has NOT already been explicitly set
  626. get_property(_sb_${dep}_USE_SYSTEM_VAR GLOBAL PROPERTY SB_${dep}_USE_SYSTEM_VAR)
  627. if(_sb_USE_SYSTEM AND NOT DEFINED ${_sb_${dep}_USE_SYSTEM_VAR})
  628. set_property(GLOBAL PROPERTY SB_${dep}_USE_SYSTEM ${_sb_USE_SYSTEM})
  629. #message(${_sb_proj} "Property SB_${dep}_USE_SYSTEM set to [${_sb_USE_SYSTEM_VAR}:${_sb_USE_SYSTEM}]")
  630. endif()
  631. endif()
  632. _sb_is_optional(${dep} _optional)
  633. set_property(GLOBAL PROPERTY SB_${dep}_OPTIONAL ${_optional})
  634. #message(${_sb_proj} "[${_sb_proj}] Property SB_${dep}_OPTIONAL set to ${_optional}")
  635. if(NOT _optional)
  636. list(APPEND _sb_REQUIRED_DEPENDS ${dep})
  637. endif()
  638. endforeach()
  639. # Display dependency of project being processed
  640. if(_sb_REQUIRED_DEPENDS AND SB_SECOND_PASS AND ${_sb_SB_VAR})
  641. set(dependency_str "")
  642. foreach(dep ${_sb_REQUIRED_DEPENDS})
  643. get_property(_is_included GLOBAL PROPERTY SB_${dep}_FILE_INCLUDED)
  644. set(_include_status "")
  645. if(_is_included)
  646. set(_include_status "[INCLUDED]")
  647. endif()
  648. set(dependency_str "${dependency_str}${dep}${_include_status}, ")
  649. endforeach()
  650. ExternalProject_Message(${_sb_proj} "${_sb_proj} => Requires ${dependency_str}")
  651. endif()
  652. # Save variables
  653. set_property(GLOBAL PROPERTY SB_${_sb_proj}_REQUIRED_DEPENDS ${_sb_REQUIRED_DEPENDS})
  654. set_property(GLOBAL PROPERTY SB_${_sb_proj}_DEPENDS ${_sb_DEPENDS})
  655. set_property(GLOBAL PROPERTY SB_${_sb_proj}_DEPENDS_VAR ${_sb_DEPENDS_VAR})
  656. set_property(GLOBAL PROPERTY SB_${_sb_proj}_EP_ARGS_VAR ${_sb_EP_ARGS_VAR})
  657. set_property(GLOBAL PROPERTY SB_${_sb_proj}_USE_SYSTEM ${_sb_USE_SYSTEM})
  658. set_property(GLOBAL PROPERTY SB_${_sb_proj}_USE_SYSTEM_VAR ${_sb_USE_SYSTEM_VAR})
  659. set_property(GLOBAL PROPERTY SB_${_sb_proj}_PROJECT_VAR ${_sb_PROJECT_VAR})
  660. foreach(varname IN ITEMS
  661. "CMAKE_GENERATOR"
  662. "CMAKE_GENERATOR_PLATFORM"
  663. "CMAKE_GENERATOR_TOOLSET"
  664. )
  665. set_property(GLOBAL PROPERTY SB_${_sb_proj}_${varname} ${_sb_${varname}})
  666. endforeach()
  667. superbuild_stack_push(SB_PROJECT_STACK ${_sb_proj})
  668. # Include dependencies
  669. foreach(dep ${_sb_DEPENDS})
  670. get_property(_included GLOBAL PROPERTY SB_${dep}_FILE_INCLUDED)
  671. if(NOT _included)
  672. # XXX - Refactor - Add a single variable named 'EXTERNAL_PROJECT_DIRS'
  673. if(EXISTS "${EXTERNAL_PROJECT_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake")
  674. include(${EXTERNAL_PROJECT_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake)
  675. elseif(EXISTS "${${dep}_FILEPATH}")
  676. include(${${dep}_FILEPATH})
  677. elseif(EXISTS "${EXTERNAL_PROJECT_ADDITIONAL_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake")
  678. include(${EXTERNAL_PROJECT_ADDITIONAL_DIR}/${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake)
  679. else()
  680. message(FATAL_ERROR "Can't find ${EXTERNAL_PROJECT_FILE_PREFIX}${dep}.cmake")
  681. endif()
  682. set_property(GLOBAL PROPERTY SB_${dep}_FILE_INCLUDED 1)
  683. endif()
  684. endforeach()
  685. # Restore variables
  686. superbuild_stack_pop(SB_PROJECT_STACK _sb_proj)
  687. foreach(varname IN ITEMS
  688. "CMAKE_GENERATOR"
  689. "CMAKE_GENERATOR_PLATFORM"
  690. "CMAKE_GENERATOR_TOOLSET"
  691. )
  692. get_property(_sb_${varname} GLOBAL PROPERTY SB_${_sb_proj}_${varname})
  693. endforeach()
  694. get_property(_sb_PROJECT_VAR GLOBAL PROPERTY SB_${_sb_proj}_PROJECT_VAR)
  695. get_property(_sb_USE_SYSTEM_VAR GLOBAL PROPERTY SB_${_sb_proj}_USE_SYSTEM_VAR)
  696. get_property(_sb_USE_SYSTEM GLOBAL PROPERTY SB_${_sb_proj}_USE_SYSTEM)
  697. get_property(_sb_EP_ARGS_VAR GLOBAL PROPERTY SB_${_sb_proj}_EP_ARGS_VAR)
  698. get_property(_sb_DEPENDS_VAR GLOBAL PROPERTY SB_${_sb_proj}_DEPENDS_VAR)
  699. get_property(_sb_DEPENDS GLOBAL PROPERTY SB_${_sb_proj}_DEPENDS)
  700. get_property(_sb_REQUIRED_DEPENDS GLOBAL PROPERTY SB_${_sb_proj}_REQUIRED_DEPENDS)
  701. # Use system ?
  702. set(_include_type "")
  703. if(_sb_USE_SYSTEM)
  704. set(_include_type " (SYSTEM)")
  705. endif()
  706. get_property(_optional GLOBAL PROPERTY SB_${_sb_proj}_OPTIONAL)
  707. ExternalProject_Message(${_sb_proj} "${_sb_proj}[OK]${_include_type}" SB_SECOND_PASS AND ${_sb_SB_VAR} AND NOT _optional)
  708. if(${_sb_proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT} AND SB_FIRST_PASS)
  709. set(SB_FIRST_PASS FALSE)
  710. ExternalProject_Message(${_sb_proj} "First pass - done")
  711. if(${_sb_SB_VAR})
  712. foreach(possible_proj ${SB_${SUPERBUILD_TOPLEVEL_PROJECT}_POSSIBLE_DEPENDS})
  713. get_property(_optional GLOBAL PROPERTY SB_${possible_proj}_OPTIONAL)
  714. if(_optional)
  715. ExternalProject_Message(${_sb_proj} "${possible_proj}[OPTIONAL]")
  716. endif()
  717. set_property(GLOBAL PROPERTY SB_${possible_proj}_FILE_INCLUDED 0)
  718. endforeach()
  719. set(${_sb_PROJECT_VAR} ${_sb_proj})
  720. set(SB_SECOND_PASS TRUE)
  721. set(_ep_include_deps_EXTRA_ARGS )
  722. foreach(varname IN ITEMS
  723. "CMAKE_GENERATOR"
  724. "CMAKE_GENERATOR_PLATFORM"
  725. "CMAKE_GENERATOR_TOOLSET"
  726. )
  727. list(APPEND _ep_include_deps_EXTRA_ARGS
  728. ${varname} ${_sb_${varname}}
  729. )
  730. endforeach()
  731. ExternalProject_Include_Dependencies(${_sb_proj}
  732. PROJECT_VAR ${_sb_PROJECT_VAR}
  733. DEPENDS_VAR ${_sb_DEPENDS_VAR}
  734. EP_ARGS_VAR ${_sb_EP_ARGS_VAR}
  735. USE_SYSTEM_VAR _sb_USE_SYSTEM
  736. SUPERBUILD_VAR ${_sb_SB_VAR}
  737. ${_ep_include_deps_EXTRA_ARGS}
  738. )
  739. set(SB_SECOND_PASS FALSE)
  740. endif()
  741. endif()
  742. if(SB_FIRST_PASS OR _optional)
  743. if(NOT ${_sb_proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT})
  744. return()
  745. endif()
  746. endif()
  747. if(SB_SECOND_PASS)
  748. _sb_get_external_project_arguments(${_sb_proj} ${_sb_EP_ARGS_VAR})
  749. endif()
  750. if(NOT SB_FIRST_PASS AND NOT SB_SECOND_PASS
  751. AND ${_sb_proj} STREQUAL ${SUPERBUILD_TOPLEVEL_PROJECT})
  752. #ExternalProject_Message(${_sb_proj} "Clean up")
  753. unset(_sb_SB_VAR)
  754. unset(SB_FIRST_PASS)
  755. unset(SB_SECOND_PASS)
  756. endif()
  757. # Set public variables
  758. set(${_sb_PROJECT_VAR} ${_sb_proj})
  759. set(${_sb_DEPENDS_VAR} ${_sb_REQUIRED_DEPENDS})
  760. set(${_sb_USE_SYSTEM_VAR} ${_sb_USE_SYSTEM})
  761. #message("[${_sb_proj}] #################################")
  762. #message("[${_sb_proj}] Setting ${_sb_PROJECT_VAR}:${_sb_proj}")
  763. #message("[${_sb_proj}] Setting ${_sb_EP_ARGS_VAR}:${${_sb_EP_ARGS_VAR}}")
  764. #message("[${_sb_proj}] Setting ${_sb_DEPENDS_VAR}:${${_sb_DEPENDS_VAR}}")
  765. #message("[${_sb_proj}] Setting ${_sb_USE_SYSTEM_VAR}:${_sb_USE_SYSTEM}")
  766. endmacro()
  767. #.rst:
  768. # .. cmake:function:: ExternalProject_Add_Empty
  769. #
  770. # .. code-block:: cmake
  771. #
  772. # ExternalProject_Add_Empty(<project_name>
  773. # DEPENDS <depends>
  774. # )
  775. #
  776. macro(ExternalProject_Add_Empty project_name)
  777. set(options)
  778. set(oneValueArgs)
  779. set(multiValueArgs DEPENDS)
  780. cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  781. # Sanity checks
  782. if(x${project_name} STREQUAL xDEPENDS)
  783. message(FATAL_ERROR "Argument <project_name> is missing !")
  784. endif()
  785. if(_sb_UNPARSED_ARGUMENTS)
  786. message(FATAL_ERROR "Invalid arguments: ${_sb_UNPARSED_ARGUMENTS}")
  787. endif()
  788. ExternalProject_Add(${project_name}
  789. SOURCE_DIR ${CMAKE_BINARY_DIR}/${project_name}
  790. BINARY_DIR ${project_name}-build
  791. DOWNLOAD_COMMAND ""
  792. CONFIGURE_COMMAND ""
  793. BUILD_COMMAND ""
  794. INSTALL_COMMAND ""
  795. DEPENDS ${_sb_DEPENDS}
  796. )
  797. endmacro()
  798. #.rst:
  799. # .. cmake:function:: ExternalProject_Install_CMake
  800. #
  801. # Install an external CMake-based project as part of the ``install`` target.
  802. #
  803. # .. code-block:: cmake
  804. #
  805. # ExternalProject_Install_CMake(<project_name>)
  806. #
  807. # This causes building the main project's ``install`` target to also execute
  808. # the CMake install script for the specified external project. The project must
  809. # be previously declared with :command:`ExternalProject_Add`.
  810. #
  811. function(ExternalProject_Install_CMake project_name)
  812. ExternalProject_Get_Property(${project_name} binary_dir)
  813. install(SCRIPT ${binary_dir}/cmake_install.cmake)
  814. endfunction()
  815. #.rst:
  816. # .. cmake:function:: ExternalProject_SetIfNotDefined
  817. #
  818. # Set a variable to its default value if not already defined.
  819. #
  820. # .. code-block:: cmake
  821. #
  822. # ExternalProject_SetIfNotDefined(<var> <defaultvalue> [OBFUSCATE] [QUIET])
  823. #
  824. # The default value is set with:
  825. # (1) if set, the value environment variable <var>.
  826. # (2) if set, the value of local variable variable <var>.
  827. # (3) if none of the above, the value passed as a parameter.
  828. #
  829. # Setting the optional parameter 'OBFUSCATE' will display 'OBFUSCATED' instead of the real value.
  830. # Setting the optional parameter 'QUIET' will not display any message.
  831. macro(ExternalProject_SetIfNotDefined var defaultvalue)
  832. set(_obfuscate FALSE)
  833. set(_quiet FALSE)
  834. foreach(arg ${ARGN})
  835. if(arg STREQUAL "OBFUSCATE")
  836. set(_obfuscate TRUE)
  837. endif()
  838. if(arg STREQUAL "QUIET")
  839. set(_quiet TRUE)
  840. endif()
  841. endforeach()
  842. if(DEFINED ENV{${var}} AND NOT DEFINED ${var})
  843. set(_value "$ENV{${var}}")
  844. if(_obfuscate)
  845. set(_value "OBFUSCATED")
  846. endif()
  847. if(NOT _quiet)
  848. message(STATUS "Setting '${var}' variable with environment variable value '${_value}'")
  849. endif()
  850. set(${var} $ENV{${var}})
  851. endif()
  852. if(NOT DEFINED ${var})
  853. set(_value "${defaultvalue}")
  854. if(_obfuscate)
  855. set(_value "OBFUSCATED")
  856. endif()
  857. if(NOT _quiet)
  858. message(STATUS "Setting '${var}' variable with default value '${_value}'")
  859. endif()
  860. set(${var} "${defaultvalue}")
  861. endif()
  862. endmacro()
  863. #.rst:
  864. # .. cmake:function:: ExternalProject_AlwaysConfigure
  865. #
  866. # Add a external project step named `forceconfigure` to `project_name` ensuring
  867. # the project will always be reconfigured.
  868. #
  869. # .. code-block:: cmake
  870. #
  871. # ExternalProject_AlwaysConfigure(<project_name>)
  872. function(ExternalProject_AlwaysConfigure proj)
  873. # This custom external project step forces the configure and later
  874. # steps to run.
  875. _ep_get_step_stampfile(${proj} "configure" stampfile)
  876. ExternalProject_Add_Step(${proj} forceconfigure
  877. COMMAND ${CMAKE_COMMAND} -E remove ${stampfile}
  878. COMMENT "Forcing configure step for '${proj}'"
  879. DEPENDEES build
  880. ALWAYS 1
  881. )
  882. endfunction()