download.cmake.in 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file Copyright.txt or https://cmake.org/licensing for details.
  3. cmake_minimum_required(VERSION 3.5)
  4. function(check_file_hash has_hash hash_is_good)
  5. if("${has_hash}" STREQUAL "")
  6. message(FATAL_ERROR "has_hash Can't be empty")
  7. endif()
  8. if("${hash_is_good}" STREQUAL "")
  9. message(FATAL_ERROR "hash_is_good Can't be empty")
  10. endif()
  11. if("@ALGO@" STREQUAL "")
  12. # No check
  13. set("${has_hash}" FALSE PARENT_SCOPE)
  14. set("${hash_is_good}" FALSE PARENT_SCOPE)
  15. return()
  16. endif()
  17. set("${has_hash}" TRUE PARENT_SCOPE)
  18. message(STATUS "verifying file...
  19. file='@LOCAL@'")
  20. file("@ALGO@" "@LOCAL@" actual_value)
  21. if(NOT "${actual_value}" STREQUAL "@EXPECT_VALUE@")
  22. set("${hash_is_good}" FALSE PARENT_SCOPE)
  23. message(STATUS "@ALGO@ hash of
  24. @LOCAL@
  25. does not match expected value
  26. expected: '@EXPECT_VALUE@'
  27. actual: '${actual_value}'")
  28. else()
  29. set("${hash_is_good}" TRUE PARENT_SCOPE)
  30. endif()
  31. endfunction()
  32. function(sleep_before_download attempt)
  33. if(attempt EQUAL 0)
  34. return()
  35. endif()
  36. if(attempt EQUAL 1)
  37. message(STATUS "Retrying...")
  38. return()
  39. endif()
  40. set(sleep_seconds 0)
  41. if(attempt EQUAL 2)
  42. set(sleep_seconds 5)
  43. elseif(attempt EQUAL 3)
  44. set(sleep_seconds 5)
  45. elseif(attempt EQUAL 4)
  46. set(sleep_seconds 15)
  47. elseif(attempt EQUAL 5)
  48. set(sleep_seconds 60)
  49. elseif(attempt EQUAL 6)
  50. set(sleep_seconds 90)
  51. elseif(attempt EQUAL 7)
  52. set(sleep_seconds 300)
  53. else()
  54. set(sleep_seconds 1200)
  55. endif()
  56. message(STATUS "Retry after ${sleep_seconds} seconds (attempt #${attempt}) ...")
  57. execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep "${sleep_seconds}")
  58. endfunction()
  59. if("@LOCAL@" STREQUAL "")
  60. message(FATAL_ERROR "LOCAL can't be empty")
  61. endif()
  62. if("@REMOTE@" STREQUAL "")
  63. message(FATAL_ERROR "REMOTE can't be empty")
  64. endif()
  65. function(download_and_verify)
  66. if(EXISTS "@LOCAL@")
  67. check_file_hash(has_hash hash_is_good)
  68. if(has_hash)
  69. if(hash_is_good)
  70. message(STATUS
  71. "File already exists and hash match (skip download):
  72. file='@LOCAL@'
  73. @ALGO@='@EXPECT_VALUE@'"
  74. )
  75. return()
  76. else()
  77. message(STATUS "File already exists but hash mismatch. Removing...")
  78. file(REMOVE "@LOCAL@")
  79. endif()
  80. else()
  81. message(STATUS
  82. "File already exists but no hash specified (use URL_HASH):
  83. file='@LOCAL@'
  84. Old file will be removed and new file downloaded from URL."
  85. )
  86. file(REMOVE "@LOCAL@")
  87. endif()
  88. endif()
  89. set(retry_number 5)
  90. message(STATUS "Downloading...
  91. dst='@LOCAL@'
  92. timeout='@TIMEOUT_MSG@'
  93. inactivity timeout='@INACTIVITY_TIMEOUT_MSG@'"
  94. )
  95. set(download_retry_codes 7 6 8 15)
  96. set(skip_url_list)
  97. set(status_code)
  98. foreach(i RANGE ${retry_number})
  99. if(status_code IN_LIST download_retry_codes)
  100. sleep_before_download(${i})
  101. endif()
  102. foreach(url @REMOTE@)
  103. if(NOT url IN_LIST skip_url_list)
  104. message(STATUS "Using src='${url}'")
  105. @TLS_VERIFY_CODE@
  106. @TLS_CAINFO_CODE@
  107. @NETRC_CODE@
  108. @NETRC_FILE_CODE@
  109. file(
  110. DOWNLOAD
  111. "${url}" "@LOCAL@"
  112. @SHOW_PROGRESS@
  113. @TIMEOUT_ARGS@
  114. @INACTIVITY_TIMEOUT_ARGS@
  115. STATUS status
  116. LOG log
  117. @USERPWD_ARGS@
  118. @HTTP_HEADERS_ARGS@
  119. )
  120. list(GET status 0 status_code)
  121. list(GET status 1 status_string)
  122. if(status_code EQUAL 0)
  123. check_file_hash(has_hash hash_is_good)
  124. if(has_hash AND NOT hash_is_good)
  125. message(STATUS "Hash mismatch, removing...")
  126. file(REMOVE "@LOCAL@")
  127. else()
  128. message(STATUS "Downloading... done")
  129. return()
  130. endif()
  131. else()
  132. string(APPEND logFailedURLs
  133. "error: downloading '${url}' failed
  134. status_code: ${status_code}
  135. status_string: ${status_string}
  136. log:
  137. --- LOG BEGIN ---
  138. ${log}
  139. --- LOG END ---
  140. "
  141. )
  142. if(NOT status_code IN_LIST download_retry_codes)
  143. list(APPEND skip_url_list "${url}")
  144. break()
  145. endif()
  146. endif()
  147. endif()
  148. endforeach()
  149. endforeach()
  150. message(FATAL_ERROR
  151. "Each download failed!
  152. ${logFailedURLs}
  153. "
  154. )
  155. endfunction()
  156. download_and_verify()
  157. set(extract_script @extract_script_filename@)
  158. if(NOT "${extract_script}" STREQUAL "")
  159. include(${extract_script})
  160. endif()