opencv/cmake/OpenCVDownload.cmake

306 lines
12 KiB
CMake
Raw Normal View History

2017-03-15 18:19:59 +08:00
#
# Download and optionally unpack a file
#
# ocv_download(FILENAME p HASH h URL u1 [u2 ...] DESTINATION_DIR d [ID id] [STATUS s] [UNPACK] [RELATIVE_URL])
2017-03-15 18:19:59 +08:00
# FILENAME - filename
# HASH - MD5 hash
# URL - full download url (first nonempty value will be chosen)
# DESTINATION_DIR - file will be copied to this directory
# ID - identifier for project/group of downloaded files
2017-03-15 18:19:59 +08:00
# STATUS - passed variable will be updated in parent scope,
# function will not fail the build in case of download problem if this option is provided,
# but will fail in case when other operations (copy, remove, etc.) failed
# UNPACK - downloaded file will be unpacked to DESTINATION_DIR
# RELATIVE_URL - if set, then URL is treated as a base, and FILENAME will be appended to it
# Note: uses OPENCV_DOWNLOAD_PATH folder as cache, default is <opencv>/.cache
set(HELP_OPENCV_DOWNLOAD_PATH "Cache directory for downloaded files")
if(DEFINED ENV{OPENCV_DOWNLOAD_PATH})
set(OPENCV_DOWNLOAD_PATH "$ENV{OPENCV_DOWNLOAD_PATH}" CACHE PATH "${HELP_OPENCV_DOWNLOAD_PATH}")
endif()
set(OPENCV_DOWNLOAD_PATH "${OpenCV_SOURCE_DIR}/.cache" CACHE PATH "${HELP_OPENCV_DOWNLOAD_PATH}")
2017-03-15 18:19:59 +08:00
set(OPENCV_DOWNLOAD_LOG "${OpenCV_BINARY_DIR}/CMakeDownloadLog.txt")
2018-08-01 20:57:53 +08:00
set(OPENCV_DOWNLOAD_WITH_CURL "${OpenCV_BINARY_DIR}/download_with_curl.sh")
set(OPENCV_DOWNLOAD_WITH_WGET "${OpenCV_BINARY_DIR}/download_with_wget.sh")
set(OPENCV_DOWNLOAD_TRIES_LIST 1 CACHE STRING "List of download tries") # a list
2021-04-26 23:01:13 +08:00
set(OPENCV_DOWNLOAD_PARAMS INACTIVITY_TIMEOUT 60 TIMEOUT 600 CACHE STRING "Download parameters to be passed to file(DOWNLOAD ...)")
mark_as_advanced(OPENCV_DOWNLOAD_TRIES_LIST OPENCV_DOWNLOAD_PARAMS)
2017-03-15 18:19:59 +08:00
2018-08-01 20:57:53 +08:00
# Init download cache directory and log file and helper scripts
2017-03-15 18:19:59 +08:00
if(NOT EXISTS "${OPENCV_DOWNLOAD_PATH}")
file(MAKE_DIRECTORY ${OPENCV_DOWNLOAD_PATH})
endif()
if(NOT EXISTS "${OPENCV_DOWNLOAD_PATH}/.gitignore")
file(WRITE "${OPENCV_DOWNLOAD_PATH}/.gitignore" "*\n")
endif()
2018-08-01 20:57:53 +08:00
file(WRITE "${OPENCV_DOWNLOAD_LOG}" "#use_cache \"${OPENCV_DOWNLOAD_PATH}\"\n")
file(REMOVE "${OPENCV_DOWNLOAD_WITH_CURL}")
file(REMOVE "${OPENCV_DOWNLOAD_WITH_WGET}")
2017-03-15 18:19:59 +08:00
Merge pull request #21531 from fengyuentau:add_3rdparty_mirrors Support downloading 3rdparty resources from Gitcode & Gitlab-style mirrors * replace github.com with gitcode.net for ocv_download * replace raw.githubusercontent.com with gitcode.net for ocv_download * rename funtions and remove some comments * add options for custom mirrors, which simply replace domain github.com & githubusercontent.com * run ocv_init_download once; replace DL_URL with mirrored one when calling ocv_download * fix for empty download links when not using mirror * fix bugs: set(.. .. PARENT_SCOPE) for ocv_init_download; correct macro names for replace github archives and raw githubusercontent * adjusted mirror swapping impl: replace with mirrored link before each ocv_download; update md5sum for archives * fix a bug: macro invoked with incorrect arguments by non-set vars * enclose if statement * workable impl * shorten the var names of two key options * scalable implementation of downloading from mirror and using custom mirror * improve ocv_init_download help message * fix the different extracted directory name in case of ADE & TBB which are downloaded from release page * improve help message printing * Download ADE & TBB using commit ids instead of from release pages * support custom mirrors on downloading archives * improve hints * add missing parentheses * reset ocv_download calls * mirror support implementation using ocv_cmake_hook & ocv_cmake_hook_append * move ocv_init_download into cmake/OpenCVDownload.cmake * move ocv_cmake_hook before checking CMake cache * improve hints when not fetching as git repo * add WORKING_DIRECTORY in execute_process in ocv_init_download * use OPENCV_DOWNLOAD_MIRROR_ID * add custom.cmake for custom mirror * detect github origin * fix broken var name * download from github by default if custom tbb is set * add checksum checks for gitcode.cmake before replacing urls and checksums * add checksum checks for custom.cmake before replacing urls and checkusms * use description specify instead of set for messages in custom.cmake; use warning message for warnings * updates and fixes
2022-03-18 17:50:21 +08:00
ocv_check_environment_variables(OPENCV_DOWNLOAD_MIRROR_ID)
function(ocv_init_download_mirror)
if(NOT DEFINED OPENCV_DOWNLOAD_MIRROR_ID)
# Run `git remote get-url origin` to get remote source
execute_process(
COMMAND
git remote get-url origin
WORKING_DIRECTORY
${CMAKE_SOURCE_DIR}
RESULT_VARIABLE
RESULT_STATUS
OUTPUT_VARIABLE
OCV_GIT_ORIGIN_URL_OUTPUT
ERROR_QUIET
)
# if non-git, OCV_GIT_ORIGIN_URL_OUTPUT is empty
if(NOT OCV_GIT_ORIGIN_URL_OUTPUT)
message(STATUS "ocv_init_download: OpenCV source tree is not fetched as git repository. 3rdparty resources will be downloaded from github.com by default.")
return()
else()
# Check if git origin is github.com
string(FIND "${OCV_GIT_ORIGIN_URL_OUTPUT}" "github.com" _found_github)
if(NOT ${_found_github} EQUAL -1)
set(OPENCV_DOWNLOAD_MIRROR_ID "github" CACHE STRING "")
endif()
# Check if git origin is gitcode.net
string(FIND "${OCV_GIT_ORIGIN_URL_OUTPUT}" "gitcode.net" _found_gitcode)
if(NOT ${_found_gitcode} EQUAL -1)
set(OPENCV_DOWNLOAD_MIRROR_ID "gitcode" CACHE STRING "")
endif()
endif()
endif()
if(OPENCV_DOWNLOAD_MIRROR_ID STREQUAL "gitcode" OR OPENCV_DOWNLOAD_MIRROR_ID STREQUAL "custom")
message(STATUS "ocv_init_download: Using ${OPENCV_DOWNLOAD_MIRROR_ID}-hosted mirror to download 3rdparty components.")
ocv_cmake_hook_append(OPENCV_DOWNLOAD_PRE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/mirrors/${OPENCV_DOWNLOAD_MIRROR_ID}.cmake")
elseif(OPENCV_DOWNLOAD_MIRROR_ID STREQUAL "github")
return()
else()
message(STATUS "ocv_init_download: Unable to recognize git server of OpenCV source code. Using github.com to download 3rdparty components.")
endif()
endfunction()
2017-03-15 18:19:59 +08:00
function(ocv_download)
cmake_parse_arguments(DL "UNPACK;RELATIVE_URL" "FILENAME;HASH;DESTINATION_DIR;ID;STATUS" "URL" ${ARGN})
function(ocv_download_log)
file(APPEND "${OPENCV_DOWNLOAD_LOG}" "${ARGN}\n")
endfunction()
ocv_assert(DL_FILENAME)
ocv_assert(DL_HASH)
ocv_assert(DL_URL)
ocv_assert(DL_DESTINATION_DIR)
if((NOT " ${DL_UNPARSED_ARGUMENTS}" STREQUAL " ")
OR DL_FILENAME STREQUAL ""
OR DL_HASH STREQUAL ""
OR DL_URL STREQUAL ""
OR DL_DESTINATION_DIR STREQUAL ""
)
set(msg_level FATAL_ERROR)
if(DEFINED DL_STATUS)
set(${DL_STATUS} FALSE PARENT_SCOPE)
set(msg_level WARNING)
endif()
message(${msg_level} "ERROR: ocv_download() unsupported arguments: ${ARGV}")
return()
endif()
2017-03-15 18:19:59 +08:00
if(DEFINED DL_STATUS)
set(${DL_STATUS} TRUE PARENT_SCOPE)
endif()
Merge pull request #21531 from fengyuentau:add_3rdparty_mirrors Support downloading 3rdparty resources from Gitcode & Gitlab-style mirrors * replace github.com with gitcode.net for ocv_download * replace raw.githubusercontent.com with gitcode.net for ocv_download * rename funtions and remove some comments * add options for custom mirrors, which simply replace domain github.com & githubusercontent.com * run ocv_init_download once; replace DL_URL with mirrored one when calling ocv_download * fix for empty download links when not using mirror * fix bugs: set(.. .. PARENT_SCOPE) for ocv_init_download; correct macro names for replace github archives and raw githubusercontent * adjusted mirror swapping impl: replace with mirrored link before each ocv_download; update md5sum for archives * fix a bug: macro invoked with incorrect arguments by non-set vars * enclose if statement * workable impl * shorten the var names of two key options * scalable implementation of downloading from mirror and using custom mirror * improve ocv_init_download help message * fix the different extracted directory name in case of ADE & TBB which are downloaded from release page * improve help message printing * Download ADE & TBB using commit ids instead of from release pages * support custom mirrors on downloading archives * improve hints * add missing parentheses * reset ocv_download calls * mirror support implementation using ocv_cmake_hook & ocv_cmake_hook_append * move ocv_init_download into cmake/OpenCVDownload.cmake * move ocv_cmake_hook before checking CMake cache * improve hints when not fetching as git repo * add WORKING_DIRECTORY in execute_process in ocv_init_download * use OPENCV_DOWNLOAD_MIRROR_ID * add custom.cmake for custom mirror * detect github origin * fix broken var name * download from github by default if custom tbb is set * add checksum checks for gitcode.cmake before replacing urls and checksums * add checksum checks for custom.cmake before replacing urls and checkusms * use description specify instead of set for messages in custom.cmake; use warning message for warnings * updates and fixes
2022-03-18 17:50:21 +08:00
ocv_cmake_hook(OPENCV_DOWNLOAD_PRE)
# Check CMake cache for already processed tasks
string(FIND "${DL_DESTINATION_DIR}" "${CMAKE_BINARY_DIR}" DL_BINARY_PATH_POS)
if(DL_BINARY_PATH_POS EQUAL 0)
set(__file_id "${DL_DESTINATION_DIR}/${DL_FILENAME}")
file(RELATIVE_PATH __file_id "${CMAKE_BINARY_DIR}" "${__file_id}")
string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" __file_id "${__file_id}")
if(DL_ID)
string(TOUPPER ${DL_ID} __id)
string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" __id "${__id}")
set(OCV_DOWNLOAD_HASH_NAME "OCV_DOWNLOAD_${__id}_HASH_${__file_id}")
else()
set(OCV_DOWNLOAD_HASH_NAME "OCV_DOWNLOAD_HASH_${__file_id}")
endif()
if(" ${${OCV_DOWNLOAD_HASH_NAME}}" STREQUAL " ${DL_HASH}")
ocv_download_log("#match_hash_in_cmake_cache \"${OCV_DOWNLOAD_HASH_NAME}\"")
return()
endif()
unset("${OCV_DOWNLOAD_HASH_NAME}" CACHE)
else()
set(OCV_DOWNLOAD_HASH_NAME "")
#message(WARNING "Download destination is not in CMAKE_BINARY_DIR=${CMAKE_BINARY_DIR}: ${DL_DESTINATION_DIR}")
endif()
2017-03-15 18:19:59 +08:00
# Select first non-empty url
foreach(url ${DL_URL})
if(url)
set(DL_URL "${url}")
break()
endif()
endforeach()
# Append filename to url if needed
if(DL_RELATIVE_URL)
set(DL_URL "${DL_URL}${DL_FILENAME}")
endif()
set(mode "copy")
if(DL_UNPACK)
set(mode "unpack")
endif()
# Log all calls to file
2018-08-01 20:57:53 +08:00
ocv_download_log("#do_${mode} \"${DL_FILENAME}\" \"${DL_HASH}\" \"${DL_URL}\" \"${DL_DESTINATION_DIR}\"")
2017-03-15 18:19:59 +08:00
# ... and to console
set(__msg_prefix "")
if(DL_ID)
set(__msg_prefix "${DL_ID}: ")
endif()
Merge pull request #21531 from fengyuentau:add_3rdparty_mirrors Support downloading 3rdparty resources from Gitcode & Gitlab-style mirrors * replace github.com with gitcode.net for ocv_download * replace raw.githubusercontent.com with gitcode.net for ocv_download * rename funtions and remove some comments * add options for custom mirrors, which simply replace domain github.com & githubusercontent.com * run ocv_init_download once; replace DL_URL with mirrored one when calling ocv_download * fix for empty download links when not using mirror * fix bugs: set(.. .. PARENT_SCOPE) for ocv_init_download; correct macro names for replace github archives and raw githubusercontent * adjusted mirror swapping impl: replace with mirrored link before each ocv_download; update md5sum for archives * fix a bug: macro invoked with incorrect arguments by non-set vars * enclose if statement * workable impl * shorten the var names of two key options * scalable implementation of downloading from mirror and using custom mirror * improve ocv_init_download help message * fix the different extracted directory name in case of ADE & TBB which are downloaded from release page * improve help message printing * Download ADE & TBB using commit ids instead of from release pages * support custom mirrors on downloading archives * improve hints * add missing parentheses * reset ocv_download calls * mirror support implementation using ocv_cmake_hook & ocv_cmake_hook_append * move ocv_init_download into cmake/OpenCVDownload.cmake * move ocv_cmake_hook before checking CMake cache * improve hints when not fetching as git repo * add WORKING_DIRECTORY in execute_process in ocv_init_download * use OPENCV_DOWNLOAD_MIRROR_ID * add custom.cmake for custom mirror * detect github origin * fix broken var name * download from github by default if custom tbb is set * add checksum checks for gitcode.cmake before replacing urls and checksums * add checksum checks for custom.cmake before replacing urls and checkusms * use description specify instead of set for messages in custom.cmake; use warning message for warnings * updates and fixes
2022-03-18 17:50:21 +08:00
message(STATUS "${__msg_prefix}Downloading ${DL_FILENAME} from ${DL_URL}")
2017-03-15 18:19:59 +08:00
# Copy mode: check if copy destination exists and is correct
if(NOT DL_UNPACK)
set(COPY_DESTINATION "${DL_DESTINATION_DIR}/${DL_FILENAME}")
if(EXISTS "${COPY_DESTINATION}")
ocv_download_log("#check_md5 \"${COPY_DESTINATION}\"")
2017-03-15 18:19:59 +08:00
file(MD5 "${COPY_DESTINATION}" target_md5)
if(target_md5 STREQUAL DL_HASH)
ocv_download_log("#match_md5 \"${COPY_DESTINATION}\" \"${target_md5}\"")
if(OCV_DOWNLOAD_HASH_NAME)
set(${OCV_DOWNLOAD_HASH_NAME} "${DL_HASH}" CACHE INTERNAL "")
endif()
2017-03-15 18:19:59 +08:00
return()
endif()
ocv_download_log("#mismatch_md5 \"${COPY_DESTINATION}\" \"${target_md5}\"")
else()
ocv_download_log("#missing \"${COPY_DESTINATION}\"")
2017-03-15 18:19:59 +08:00
endif()
endif()
# Check cache first
if(DL_ID)
string(TOLOWER "${DL_ID}" __id)
string(REGEX REPLACE "[^a-zA-Z0-9_/ ]" "_" __id "${__id}")
set(CACHE_CANDIDATE "${OPENCV_DOWNLOAD_PATH}/${__id}/${DL_HASH}-${DL_FILENAME}")
else()
set(CACHE_CANDIDATE "${OPENCV_DOWNLOAD_PATH}/${DL_HASH}-${DL_FILENAME}")
endif()
2017-03-15 18:19:59 +08:00
if(EXISTS "${CACHE_CANDIDATE}")
ocv_download_log("#check_md5 \"${CACHE_CANDIDATE}\"")
2017-03-15 18:19:59 +08:00
file(MD5 "${CACHE_CANDIDATE}" target_md5)
if(NOT target_md5 STREQUAL DL_HASH)
ocv_download_log("#mismatch_md5 \"${CACHE_CANDIDATE}\" \"${target_md5}\"")
ocv_download_log("#delete \"${CACHE_CANDIDATE}\"")
2017-03-15 18:19:59 +08:00
file(REMOVE ${CACHE_CANDIDATE})
endif()
endif()
# Download
if(NOT EXISTS "${CACHE_CANDIDATE}")
ocv_download_log("#cmake_download \"${CACHE_CANDIDATE}\" \"${DL_URL}\"")
foreach(try ${OPENCV_DOWNLOAD_TRIES_LIST})
ocv_download_log("#try ${try}")
file(DOWNLOAD "${DL_URL}" "${CACHE_CANDIDATE}"
STATUS status
LOG __log
${OPENCV_DOWNLOAD_PARAMS})
if(status EQUAL 0)
break()
endif()
message(STATUS "Try ${try} failed")
endforeach()
if(NOT OPENCV_SKIP_FILE_DOWNLOAD_DUMP) # workaround problem with old CMake versions: "Invalid escape sequence"
string(LENGTH "${__log}" __log_length)
if(__log_length LESS 65536)
string(REPLACE "\n" "\n# " __log "${__log}")
ocv_download_log("# ${__log}\n")
endif()
endif()
2017-03-15 18:19:59 +08:00
if(NOT status EQUAL 0)
set(msg_level FATAL_ERROR)
if(DEFINED DL_STATUS)
set(${DL_STATUS} FALSE PARENT_SCOPE)
set(msg_level WARNING)
endif()
if(status MATCHES "Couldn't resolve host name")
message(STATUS "
=======================================================================
Couldn't download files from the Internet.
Please check the Internet access on this host.
=======================================================================
")
elseif(status MATCHES "Couldn't connect to server")
message(STATUS "
=======================================================================
Couldn't connect to server from the Internet.
Perhaps direct connections are not allowed in the current network.
To use proxy please check/specify these environment variables:
- http_proxy/https_proxy
- and/or HTTP_PROXY/HTTPS_PROXY
=======================================================================
")
endif()
message(${msg_level} "${__msg_prefix}Download failed: ${status}
For details please refer to the download log file:
${OPENCV_DOWNLOAD_LOG}
")
2018-08-01 20:57:53 +08:00
# write helper scripts for failed downloads
file(APPEND "${OPENCV_DOWNLOAD_WITH_CURL}" "curl --create-dirs --output \"${CACHE_CANDIDATE}\" \"${DL_URL}\"\n")
file(APPEND "${OPENCV_DOWNLOAD_WITH_WGET}" "mkdir -p $(dirname ${CACHE_CANDIDATE}) && wget -O \"${CACHE_CANDIDATE}\" \"${DL_URL}\"\n")
2017-03-15 18:19:59 +08:00
return()
endif()
# Don't remove this code, because EXPECTED_MD5 parameter doesn't fail "file(DOWNLOAD)" step on wrong hash
ocv_download_log("#check_md5 \"${CACHE_CANDIDATE}\"")
2017-03-15 18:19:59 +08:00
file(MD5 "${CACHE_CANDIDATE}" target_md5)
if(NOT target_md5 STREQUAL DL_HASH)
ocv_download_log("#mismatch_md5 \"${CACHE_CANDIDATE}\" \"${target_md5}\"")
2017-03-15 18:19:59 +08:00
set(msg_level FATAL_ERROR)
if(DEFINED DL_STATUS)
set(${DL_STATUS} FALSE PARENT_SCOPE)
set(msg_level WARNING)
endif()
message(${msg_level} "${__msg_prefix}Hash mismatch: ${target_md5}")
2017-03-15 18:19:59 +08:00
return()
endif()
endif()
# Unpack or copy
if(DL_UNPACK)
if(EXISTS "${DL_DESTINATION_DIR}")
ocv_download_log("#remove_unpack \"${DL_DESTINATION_DIR}\"")
2017-03-15 18:19:59 +08:00
file(REMOVE_RECURSE "${DL_DESTINATION_DIR}")
endif()
ocv_download_log("#mkdir \"${DL_DESTINATION_DIR}\"")
2017-03-15 18:19:59 +08:00
file(MAKE_DIRECTORY "${DL_DESTINATION_DIR}")
ocv_download_log("#unpack \"${DL_DESTINATION_DIR}\" \"${CACHE_CANDIDATE}\"")
execute_process(COMMAND "${CMAKE_COMMAND}" -E tar xzf "${CACHE_CANDIDATE}"
2017-03-15 18:19:59 +08:00
WORKING_DIRECTORY "${DL_DESTINATION_DIR}"
RESULT_VARIABLE res)
if(NOT res EQUAL 0)
message(FATAL_ERROR "${__msg_prefix}Unpack failed: ${res}")
2017-03-15 18:19:59 +08:00
endif()
else()
ocv_download_log("#copy \"${COPY_DESTINATION}\" \"${CACHE_CANDIDATE}\"")
2017-03-15 18:19:59 +08:00
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CACHE_CANDIDATE}" "${COPY_DESTINATION}"
RESULT_VARIABLE res)
if(NOT res EQUAL 0)
message(FATAL_ERROR "${__msg_prefix}Copy failed: ${res}")
2017-03-15 18:19:59 +08:00
endif()
endif()
if(OCV_DOWNLOAD_HASH_NAME)
set(${OCV_DOWNLOAD_HASH_NAME} "${DL_HASH}" CACHE INTERNAL "")
endif()
2017-03-15 18:19:59 +08:00
endfunction()
Merge pull request #21531 from fengyuentau:add_3rdparty_mirrors Support downloading 3rdparty resources from Gitcode & Gitlab-style mirrors * replace github.com with gitcode.net for ocv_download * replace raw.githubusercontent.com with gitcode.net for ocv_download * rename funtions and remove some comments * add options for custom mirrors, which simply replace domain github.com & githubusercontent.com * run ocv_init_download once; replace DL_URL with mirrored one when calling ocv_download * fix for empty download links when not using mirror * fix bugs: set(.. .. PARENT_SCOPE) for ocv_init_download; correct macro names for replace github archives and raw githubusercontent * adjusted mirror swapping impl: replace with mirrored link before each ocv_download; update md5sum for archives * fix a bug: macro invoked with incorrect arguments by non-set vars * enclose if statement * workable impl * shorten the var names of two key options * scalable implementation of downloading from mirror and using custom mirror * improve ocv_init_download help message * fix the different extracted directory name in case of ADE & TBB which are downloaded from release page * improve help message printing * Download ADE & TBB using commit ids instead of from release pages * support custom mirrors on downloading archives * improve hints * add missing parentheses * reset ocv_download calls * mirror support implementation using ocv_cmake_hook & ocv_cmake_hook_append * move ocv_init_download into cmake/OpenCVDownload.cmake * move ocv_cmake_hook before checking CMake cache * improve hints when not fetching as git repo * add WORKING_DIRECTORY in execute_process in ocv_init_download * use OPENCV_DOWNLOAD_MIRROR_ID * add custom.cmake for custom mirror * detect github origin * fix broken var name * download from github by default if custom tbb is set * add checksum checks for gitcode.cmake before replacing urls and checksums * add checksum checks for custom.cmake before replacing urls and checkusms * use description specify instead of set for messages in custom.cmake; use warning message for warnings * updates and fixes
2022-03-18 17:50:21 +08:00
# ----------------------------------------------------------------------------
# Initialize download in case mirror is used
# ----------------------------------------------------------------------------
ocv_init_download_mirror()