HunterGate.cmake 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. # Copyright (c) 2013-2017, Ruslan Baratov
  2. # All rights reserved.
  3. #
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions are met:
  6. #
  7. # * Redistributions of source code must retain the above copyright notice, this
  8. # list of conditions and the following disclaimer.
  9. #
  10. # * Redistributions in binary form must reproduce the above copyright notice,
  11. # this list of conditions and the following disclaimer in the documentation
  12. # and/or other materials provided with the distribution.
  13. #
  14. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  15. # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  18. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  20. # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  21. # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  22. # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. # This is a gate file to Hunter package manager.
  25. # Include this file using `include` command and add package you need, example:
  26. #
  27. # cmake_minimum_required(VERSION 3.0)
  28. #
  29. # include("cmake/HunterGate.cmake")
  30. # HunterGate(
  31. # URL "https://github.com/path/to/hunter/archive.tar.gz"
  32. # SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d"
  33. # )
  34. #
  35. # project(MyProject)
  36. #
  37. # hunter_add_package(Foo)
  38. # hunter_add_package(Boo COMPONENTS Bar Baz)
  39. #
  40. # Projects:
  41. # * https://github.com/hunter-packages/gate/
  42. # * https://github.com/ruslo/hunter
  43. option(HUNTER_ENABLED "Enable Hunter package manager support" ON)
  44. if(HUNTER_ENABLED)
  45. if(CMAKE_VERSION VERSION_LESS "3.0")
  46. message(FATAL_ERROR "At least CMake version 3.0 required for hunter dependency management."
  47. " Update CMake or set HUNTER_ENABLED to OFF.")
  48. endif()
  49. endif()
  50. include(CMakeParseArguments) # cmake_parse_arguments
  51. option(HUNTER_STATUS_PRINT "Print working status" ON)
  52. option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
  53. option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON)
  54. set(HUNTER_WIKI "https://github.com/ruslo/hunter/wiki")
  55. function(hunter_gate_status_print)
  56. if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
  57. foreach(print_message ${ARGV})
  58. message(STATUS "[hunter] ${print_message}")
  59. endforeach()
  60. endif()
  61. endfunction()
  62. function(hunter_gate_status_debug)
  63. if(HUNTER_STATUS_DEBUG)
  64. foreach(print_message ${ARGV})
  65. string(TIMESTAMP timestamp)
  66. message(STATUS "[hunter *** DEBUG *** ${timestamp}] ${print_message}")
  67. endforeach()
  68. endif()
  69. endfunction()
  70. function(hunter_gate_wiki wiki_page)
  71. message("------------------------------ WIKI -------------------------------")
  72. message(" ${HUNTER_WIKI}/${wiki_page}")
  73. message("-------------------------------------------------------------------")
  74. message("")
  75. message(FATAL_ERROR "")
  76. endfunction()
  77. function(hunter_gate_internal_error)
  78. message("")
  79. foreach(print_message ${ARGV})
  80. message("[hunter ** INTERNAL **] ${print_message}")
  81. endforeach()
  82. message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
  83. message("")
  84. hunter_gate_wiki("error.internal")
  85. endfunction()
  86. function(hunter_gate_fatal_error)
  87. cmake_parse_arguments(hunter "" "WIKI" "" "${ARGV}")
  88. string(COMPARE EQUAL "${hunter_WIKI}" "" have_no_wiki)
  89. if(have_no_wiki)
  90. hunter_gate_internal_error("Expected wiki")
  91. endif()
  92. message("")
  93. foreach(x ${hunter_UNPARSED_ARGUMENTS})
  94. message("[hunter ** FATAL ERROR **] ${x}")
  95. endforeach()
  96. message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
  97. message("")
  98. hunter_gate_wiki("${hunter_WIKI}")
  99. endfunction()
  100. function(hunter_gate_user_error)
  101. hunter_gate_fatal_error(${ARGV} WIKI "error.incorrect.input.data")
  102. endfunction()
  103. function(hunter_gate_self root version sha1 result)
  104. string(COMPARE EQUAL "${root}" "" is_bad)
  105. if(is_bad)
  106. hunter_gate_internal_error("root is empty")
  107. endif()
  108. string(COMPARE EQUAL "${version}" "" is_bad)
  109. if(is_bad)
  110. hunter_gate_internal_error("version is empty")
  111. endif()
  112. string(COMPARE EQUAL "${sha1}" "" is_bad)
  113. if(is_bad)
  114. hunter_gate_internal_error("sha1 is empty")
  115. endif()
  116. string(SUBSTRING "${sha1}" 0 7 archive_id)
  117. if(EXISTS "${root}/cmake/Hunter")
  118. set(hunter_self "${root}")
  119. else()
  120. set(
  121. hunter_self
  122. "${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked"
  123. )
  124. endif()
  125. set("${result}" "${hunter_self}" PARENT_SCOPE)
  126. endfunction()
  127. # Set HUNTER_GATE_ROOT cmake variable to suitable value.
  128. function(hunter_gate_detect_root)
  129. # Check CMake variable
  130. string(COMPARE NOTEQUAL "${HUNTER_ROOT}" "" not_empty)
  131. if(not_empty)
  132. set(HUNTER_GATE_ROOT "${HUNTER_ROOT}" PARENT_SCOPE)
  133. hunter_gate_status_debug("HUNTER_ROOT detected by cmake variable")
  134. return()
  135. endif()
  136. # Check environment variable
  137. string(COMPARE NOTEQUAL "$ENV{HUNTER_ROOT}" "" not_empty)
  138. if(not_empty)
  139. set(HUNTER_GATE_ROOT "$ENV{HUNTER_ROOT}" PARENT_SCOPE)
  140. hunter_gate_status_debug("HUNTER_ROOT detected by environment variable")
  141. return()
  142. endif()
  143. # Check HOME environment variable
  144. string(COMPARE NOTEQUAL "$ENV{HOME}" "" result)
  145. if(result)
  146. set(HUNTER_GATE_ROOT "$ENV{HOME}/.hunter" PARENT_SCOPE)
  147. hunter_gate_status_debug("HUNTER_ROOT set using HOME environment variable")
  148. return()
  149. endif()
  150. # Check SYSTEMDRIVE and USERPROFILE environment variable (windows only)
  151. if(WIN32)
  152. string(COMPARE NOTEQUAL "$ENV{SYSTEMDRIVE}" "" result)
  153. if(result)
  154. set(HUNTER_GATE_ROOT "$ENV{SYSTEMDRIVE}/.hunter" PARENT_SCOPE)
  155. hunter_gate_status_debug(
  156. "HUNTER_ROOT set using SYSTEMDRIVE environment variable"
  157. )
  158. return()
  159. endif()
  160. string(COMPARE NOTEQUAL "$ENV{USERPROFILE}" "" result)
  161. if(result)
  162. set(HUNTER_GATE_ROOT "$ENV{USERPROFILE}/.hunter" PARENT_SCOPE)
  163. hunter_gate_status_debug(
  164. "HUNTER_ROOT set using USERPROFILE environment variable"
  165. )
  166. return()
  167. endif()
  168. endif()
  169. hunter_gate_fatal_error(
  170. "Can't detect HUNTER_ROOT"
  171. WIKI "error.detect.hunter.root"
  172. )
  173. endfunction()
  174. macro(hunter_gate_lock dir)
  175. if(NOT HUNTER_SKIP_LOCK)
  176. if("${CMAKE_VERSION}" VERSION_LESS "3.2")
  177. hunter_gate_fatal_error(
  178. "Can't lock, upgrade to CMake 3.2 or use HUNTER_SKIP_LOCK"
  179. WIKI "error.can.not.lock"
  180. )
  181. endif()
  182. hunter_gate_status_debug("Locking directory: ${dir}")
  183. file(LOCK "${dir}" DIRECTORY GUARD FUNCTION)
  184. hunter_gate_status_debug("Lock done")
  185. endif()
  186. endmacro()
  187. function(hunter_gate_download dir)
  188. string(
  189. COMPARE
  190. NOTEQUAL
  191. "$ENV{HUNTER_DISABLE_AUTOINSTALL}"
  192. ""
  193. disable_autoinstall
  194. )
  195. if(disable_autoinstall AND NOT HUNTER_RUN_INSTALL)
  196. hunter_gate_fatal_error(
  197. "Hunter not found in '${dir}'"
  198. "Set HUNTER_RUN_INSTALL=ON to auto-install it from '${HUNTER_GATE_URL}'"
  199. "Settings:"
  200. " HUNTER_ROOT: ${HUNTER_GATE_ROOT}"
  201. " HUNTER_SHA1: ${HUNTER_GATE_SHA1}"
  202. WIKI "error.run.install"
  203. )
  204. endif()
  205. string(COMPARE EQUAL "${dir}" "" is_bad)
  206. if(is_bad)
  207. hunter_gate_internal_error("Empty 'dir' argument")
  208. endif()
  209. string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" is_bad)
  210. if(is_bad)
  211. hunter_gate_internal_error("HUNTER_GATE_SHA1 empty")
  212. endif()
  213. string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" is_bad)
  214. if(is_bad)
  215. hunter_gate_internal_error("HUNTER_GATE_URL empty")
  216. endif()
  217. set(done_location "${dir}/DONE")
  218. set(sha1_location "${dir}/SHA1")
  219. set(build_dir "${dir}/Build")
  220. set(cmakelists "${dir}/CMakeLists.txt")
  221. hunter_gate_lock("${dir}")
  222. if(EXISTS "${done_location}")
  223. # while waiting for lock other instance can do all the job
  224. hunter_gate_status_debug("File '${done_location}' found, skip install")
  225. return()
  226. endif()
  227. file(REMOVE_RECURSE "${build_dir}")
  228. file(REMOVE_RECURSE "${cmakelists}")
  229. file(MAKE_DIRECTORY "${build_dir}") # check directory permissions
  230. # Disabling languages speeds up a little bit, reduces noise in the output
  231. # and avoids path too long windows error
  232. file(
  233. WRITE
  234. "${cmakelists}"
  235. "cmake_minimum_required(VERSION 3.0)\n"
  236. "project(HunterDownload LANGUAGES NONE)\n"
  237. "include(ExternalProject)\n"
  238. "ExternalProject_Add(\n"
  239. " Hunter\n"
  240. " URL\n"
  241. " \"${HUNTER_GATE_URL}\"\n"
  242. " URL_HASH\n"
  243. " SHA1=${HUNTER_GATE_SHA1}\n"
  244. " DOWNLOAD_DIR\n"
  245. " \"${dir}\"\n"
  246. " TLS_VERIFY\n"
  247. " ${HUNTER_TLS_VERIFY}\n"
  248. " SOURCE_DIR\n"
  249. " \"${dir}/Unpacked\"\n"
  250. " CONFIGURE_COMMAND\n"
  251. " \"\"\n"
  252. " BUILD_COMMAND\n"
  253. " \"\"\n"
  254. " INSTALL_COMMAND\n"
  255. " \"\"\n"
  256. ")\n"
  257. )
  258. if(HUNTER_STATUS_DEBUG)
  259. set(logging_params "")
  260. else()
  261. set(logging_params OUTPUT_QUIET)
  262. endif()
  263. hunter_gate_status_debug("Run generate")
  264. # Need to add toolchain file too.
  265. # Otherwise on Visual Studio + MDD this will fail with error:
  266. # "Could not find an appropriate version of the Windows 10 SDK installed on this machine"
  267. if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
  268. get_filename_component(absolute_CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE)
  269. set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=${absolute_CMAKE_TOOLCHAIN_FILE}")
  270. else()
  271. # 'toolchain_arg' can't be empty
  272. set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=")
  273. endif()
  274. string(COMPARE EQUAL "${CMAKE_MAKE_PROGRAM}" "" no_make)
  275. if(no_make)
  276. set(make_arg "")
  277. else()
  278. # Test case: remove Ninja from PATH but set it via CMAKE_MAKE_PROGRAM
  279. set(make_arg "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}")
  280. endif()
  281. execute_process(
  282. COMMAND
  283. "${CMAKE_COMMAND}"
  284. "-H${dir}"
  285. "-B${build_dir}"
  286. "-G${CMAKE_GENERATOR}"
  287. "${toolchain_arg}"
  288. ${make_arg}
  289. WORKING_DIRECTORY "${dir}"
  290. RESULT_VARIABLE download_result
  291. ${logging_params}
  292. )
  293. if(NOT download_result EQUAL 0)
  294. hunter_gate_internal_error("Configure project failed")
  295. endif()
  296. hunter_gate_status_print(
  297. "Initializing Hunter workspace (${HUNTER_GATE_SHA1})"
  298. " ${HUNTER_GATE_URL}"
  299. " -> ${dir}"
  300. )
  301. execute_process(
  302. COMMAND "${CMAKE_COMMAND}" --build "${build_dir}"
  303. WORKING_DIRECTORY "${dir}"
  304. RESULT_VARIABLE download_result
  305. ${logging_params}
  306. )
  307. if(NOT download_result EQUAL 0)
  308. hunter_gate_internal_error("Build project failed")
  309. endif()
  310. file(REMOVE_RECURSE "${build_dir}")
  311. file(REMOVE_RECURSE "${cmakelists}")
  312. file(WRITE "${sha1_location}" "${HUNTER_GATE_SHA1}")
  313. file(WRITE "${done_location}" "DONE")
  314. hunter_gate_status_debug("Finished")
  315. endfunction()
  316. # Must be a macro so master file 'cmake/Hunter' can
  317. # apply all variables easily just by 'include' command
  318. # (otherwise PARENT_SCOPE magic needed)
  319. macro(HunterGate)
  320. if(HUNTER_GATE_DONE)
  321. # variable HUNTER_GATE_DONE set explicitly for external project
  322. # (see `hunter_download`)
  323. set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
  324. endif()
  325. # First HunterGate command will init Hunter, others will be ignored
  326. get_property(_hunter_gate_done GLOBAL PROPERTY HUNTER_GATE_DONE SET)
  327. if(NOT HUNTER_ENABLED)
  328. # Empty function to avoid error "unknown function"
  329. function(hunter_add_package)
  330. endfunction()
  331. set(
  332. _hunter_gate_disabled_mode_dir
  333. "${CMAKE_CURRENT_LIST_DIR}/cmake/Hunter/disabled-mode"
  334. )
  335. if(EXISTS "${_hunter_gate_disabled_mode_dir}")
  336. hunter_gate_status_debug(
  337. "Adding \"disabled-mode\" modules: ${_hunter_gate_disabled_mode_dir}"
  338. )
  339. list(APPEND CMAKE_PREFIX_PATH "${_hunter_gate_disabled_mode_dir}")
  340. endif()
  341. elseif(_hunter_gate_done)
  342. hunter_gate_status_debug("Secondary HunterGate (use old settings)")
  343. hunter_gate_self(
  344. "${HUNTER_CACHED_ROOT}"
  345. "${HUNTER_VERSION}"
  346. "${HUNTER_SHA1}"
  347. _hunter_self
  348. )
  349. include("${_hunter_self}/cmake/Hunter")
  350. else()
  351. set(HUNTER_GATE_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
  352. string(COMPARE NOTEQUAL "${PROJECT_NAME}" "" _have_project_name)
  353. if(_have_project_name)
  354. hunter_gate_fatal_error(
  355. "Please set HunterGate *before* 'project' command. "
  356. "Detected project: ${PROJECT_NAME}"
  357. WIKI "error.huntergate.before.project"
  358. )
  359. endif()
  360. cmake_parse_arguments(
  361. HUNTER_GATE "LOCAL" "URL;SHA1;GLOBAL;FILEPATH" "" ${ARGV}
  362. )
  363. string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" _empty_sha1)
  364. string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" _empty_url)
  365. string(
  366. COMPARE
  367. NOTEQUAL
  368. "${HUNTER_GATE_UNPARSED_ARGUMENTS}"
  369. ""
  370. _have_unparsed
  371. )
  372. string(COMPARE NOTEQUAL "${HUNTER_GATE_GLOBAL}" "" _have_global)
  373. string(COMPARE NOTEQUAL "${HUNTER_GATE_FILEPATH}" "" _have_filepath)
  374. if(_have_unparsed)
  375. hunter_gate_user_error(
  376. "HunterGate unparsed arguments: ${HUNTER_GATE_UNPARSED_ARGUMENTS}"
  377. )
  378. endif()
  379. if(_empty_sha1)
  380. hunter_gate_user_error("SHA1 suboption of HunterGate is mandatory")
  381. endif()
  382. if(_empty_url)
  383. hunter_gate_user_error("URL suboption of HunterGate is mandatory")
  384. endif()
  385. if(_have_global)
  386. if(HUNTER_GATE_LOCAL)
  387. hunter_gate_user_error("Unexpected LOCAL (already has GLOBAL)")
  388. endif()
  389. if(_have_filepath)
  390. hunter_gate_user_error("Unexpected FILEPATH (already has GLOBAL)")
  391. endif()
  392. endif()
  393. if(HUNTER_GATE_LOCAL)
  394. if(_have_global)
  395. hunter_gate_user_error("Unexpected GLOBAL (already has LOCAL)")
  396. endif()
  397. if(_have_filepath)
  398. hunter_gate_user_error("Unexpected FILEPATH (already has LOCAL)")
  399. endif()
  400. endif()
  401. if(_have_filepath)
  402. if(_have_global)
  403. hunter_gate_user_error("Unexpected GLOBAL (already has FILEPATH)")
  404. endif()
  405. if(HUNTER_GATE_LOCAL)
  406. hunter_gate_user_error("Unexpected LOCAL (already has FILEPATH)")
  407. endif()
  408. endif()
  409. hunter_gate_detect_root() # set HUNTER_GATE_ROOT
  410. # Beautify path, fix probable problems with windows path slashes
  411. get_filename_component(
  412. HUNTER_GATE_ROOT "${HUNTER_GATE_ROOT}" ABSOLUTE
  413. )
  414. hunter_gate_status_debug("HUNTER_ROOT: ${HUNTER_GATE_ROOT}")
  415. if(NOT HUNTER_ALLOW_SPACES_IN_PATH)
  416. string(FIND "${HUNTER_GATE_ROOT}" " " _contain_spaces)
  417. if(NOT _contain_spaces EQUAL -1)
  418. hunter_gate_fatal_error(
  419. "HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces."
  420. "Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error"
  421. "(Use at your own risk!)"
  422. WIKI "error.spaces.in.hunter.root"
  423. )
  424. endif()
  425. endif()
  426. string(
  427. REGEX
  428. MATCH
  429. "[0-9]+\\.[0-9]+\\.[0-9]+[-_a-z0-9]*"
  430. HUNTER_GATE_VERSION
  431. "${HUNTER_GATE_URL}"
  432. )
  433. string(COMPARE EQUAL "${HUNTER_GATE_VERSION}" "" _is_empty)
  434. if(_is_empty)
  435. set(HUNTER_GATE_VERSION "unknown")
  436. endif()
  437. hunter_gate_self(
  438. "${HUNTER_GATE_ROOT}"
  439. "${HUNTER_GATE_VERSION}"
  440. "${HUNTER_GATE_SHA1}"
  441. _hunter_self
  442. )
  443. set(_master_location "${_hunter_self}/cmake/Hunter")
  444. if(EXISTS "${HUNTER_GATE_ROOT}/cmake/Hunter")
  445. # Hunter downloaded manually (e.g. by 'git clone')
  446. set(_unused "xxxxxxxxxx")
  447. set(HUNTER_GATE_SHA1 "${_unused}")
  448. set(HUNTER_GATE_VERSION "${_unused}")
  449. else()
  450. get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE)
  451. set(_done_location "${_archive_id_location}/DONE")
  452. set(_sha1_location "${_archive_id_location}/SHA1")
  453. # Check Hunter already downloaded by HunterGate
  454. if(NOT EXISTS "${_done_location}")
  455. hunter_gate_download("${_archive_id_location}")
  456. endif()
  457. if(NOT EXISTS "${_done_location}")
  458. hunter_gate_internal_error("hunter_gate_download failed")
  459. endif()
  460. if(NOT EXISTS "${_sha1_location}")
  461. hunter_gate_internal_error("${_sha1_location} not found")
  462. endif()
  463. file(READ "${_sha1_location}" _sha1_value)
  464. string(COMPARE EQUAL "${_sha1_value}" "${HUNTER_GATE_SHA1}" _is_equal)
  465. if(NOT _is_equal)
  466. hunter_gate_internal_error(
  467. "Short SHA1 collision:"
  468. " ${_sha1_value} (from ${_sha1_location})"
  469. " ${HUNTER_GATE_SHA1} (HunterGate)"
  470. )
  471. endif()
  472. if(NOT EXISTS "${_master_location}")
  473. hunter_gate_user_error(
  474. "Master file not found:"
  475. " ${_master_location}"
  476. "try to update Hunter/HunterGate"
  477. )
  478. endif()
  479. endif()
  480. include("${_master_location}")
  481. set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
  482. endif()
  483. endmacro()