This commit is contained in:
hardliner66 2024-10-14 23:36:54 +02:00
parent c7fdb6445d
commit aeb1a72871
2 changed files with 124 additions and 114 deletions

View File

@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.11)
project(DownloadTest)
cmake_minimum_required(VERSION 3.11)
# add to module path
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
@ -11,18 +12,21 @@ include(Download)
## include("${PROJECT_SOURCE_DIR}/cmake/Download.cmake")
# use like this
download_file_with_hash_check(
"http://127.0.0.1:8080/random_file.bin"
"${CMAKE_BINARY_DIR}/random_file.bin")
# or this
download_file_with_hash_check(
"http://127.0.0.1:8080/random_file.bin"
"${CMAKE_BINARY_DIR}/random_file.bin"
REQUIRED)
# or this
# download_file_with_hash_check(URL "http://127.0.0.1:8080/random_file.bin" DEST "${CMAKE_BINARY_DIR}/random_file.bin" REQUIRED)
# # or this
# download_file_with_hash_check(
# "http://127.0.0.1:8080/random_file.bin"
# "${CMAKE_BINARY_DIR}/random_file.bin")
# # or this
# download_file_with_hash_check(
# URL "http://127.0.0.1:8080/random_file.bin"
# DEST "${CMAKE_BINARY_DIR}/random_file.bin"
# REQUIRED)
# Or include directly

View File

@ -1,129 +1,135 @@
function(check_file_reachable url)
set(oneValueArgs RESULT_VAR)
cmake_parse_arguments(PARSE_ARGV 0 ARG "" "${oneValueArgs}" "")
set(oneValueArgs RESULT_VAR)
cmake_parse_arguments(PARSE_ARGV 0 ARG "" "${oneValueArgs}" "")
set(result_var "file_reachable")
if(ARG_RESULT_VAR)
set(result_var "${ARG_RESULT_VAR}")
endif()
set(result_var "file_reachable")
if(ARG_RESULT_VAR)
set(result_var "${ARG_RESULT_VAR}")
endif()
file(
DOWNLOAD "${url}" RANGE_END
10
TIMEOUT 2
INACTIVITY_TIMEOUT 1
STATUS download_status)
file(
DOWNLOAD "${url}" RANGE_END
10
TIMEOUT 2
INACTIVITY_TIMEOUT 1
STATUS download_status)
list(GET download_status 0 download_status_code)
if("${download_status_code}" STREQUAL "0")
set(${result_var}
"1"
PARENT_SCOPE)
else()
set(${result_var}
"0"
PARENT_SCOPE)
endif()
list(GET download_status 0 download_status_code)
if("${download_status_code}" STREQUAL "0")
set(${result_var}
"1"
PARENT_SCOPE)
else()
set(${result_var}
"0"
PARENT_SCOPE)
endif()
endfunction()
function(download_file_with_hash_check url dest)
set(options REQUIRED)
set(oneValueArgs URL DEST HASH_URL)
cmake_parse_arguments(PARSE_ARGV 0 ARG "${options}" "${oneValueArgs}" "")
set(options REQUIRED)
set(oneValueArgs URL DEST HASH_URL)
cmake_parse_arguments(PARSE_ARGV 0 ARG "${options}" "${oneValueArgs}" "")
if(ARG_URL)
set(url "${ARG_URL}")
endif()
if(ARG_DEST)
set(dest "${ARG_DEST}")
endif()
set(hash_url "${url}.hash")
if(ARG_HASH_URL)
set(hash_url "${ARG_HASH_URL}")
endif()
message(STATUS "${hash_url}")
check_file_reachable("${url}" RESULT_VAR file_reachable)
if("${file_reachable}" STREQUAL "0")
if(ARG_REQUIRED)
if(NOT EXISTS "${dest}")
message(
FATAL_ERROR
"File ${dest} could not be downloaded and is not present, even though it was marked as REQUIRED."
)
endif()
if(ARG_URL)
set(url "${ARG_URL}")
endif()
return()
endif()
set(hash_file "${dest}.hash")
set(hash_file_temp "${hash_file}.temp")
if(ARG_DEST)
set(dest "${ARG_DEST}")
endif()
# Download the hash file (if available)
file(
DOWNLOAD "${hash_url}" "${hash_file_temp}"
STATUS download_status
TIMEOUT 60)
set(hash_url "${url}.hash")
list(GET download_status 0 download_status_code)
if(NOT "${download_status_code}" STREQUAL "0")
file(REMOVE "${hash_file_temp}")
# Hash file is not available, just check if the file exists
if(ARG_HASH_URL)
set(hash_url "${ARG_HASH_URL}")
endif()
check_file_reachable("${url}" RESULT_VAR file_reachable)
if("${file_reachable}" STREQUAL "0")
if(ARG_REQUIRED)
if(NOT EXISTS "${dest}")
message(
FATAL_ERROR
"File ${dest} could not be downloaded and is not present, even though it was marked as REQUIRED."
)
endif()
endif()
return()
endif()
set(hash_file "${dest}.hash")
set(hash_file_temp "${hash_file}.temp")
# Download the hash file (if available)
file(
DOWNLOAD "${hash_url}" "${hash_file_temp}"
STATUS download_status
TIMEOUT 60)
list(GET download_status 0 download_status_code)
if(NOT "${download_status_code}" STREQUAL "0")
file(REMOVE "${hash_file_temp}")
# Hash file is not available, just check if the file exists
if(EXISTS "${dest}")
message(
STATUS
"File ${dest} already exists, no hash file found. Skipping download.")
return()
else()
message(STATUS "File ${dest} not found, downloading without hash check.")
file(
DOWNLOAD "${url}" "${dest}"
SHOW_PROGRESS
TIMEOUT 60)
return()
endif()
endif()
file(READ "${hash_file_temp}" expected_hash)
string(STRIP "${expected_hash}" expected_hash)
if(NOT "${expected_hash}" STREQUAL "")
file(RENAME "${hash_file_temp}" "${hash_file}")
endif()
# Hash file downloaded, now read the hash
file(READ "${hash_file}" expected_hash)
string(STRIP "${expected_hash}" expected_hash) # Remove whitespace around hash
if(EXISTS "${dest}")
message(
STATUS
"File ${dest} already exists, no hash file found. Skipping download.")
return()
file(SHA256 "${dest}" actual_hash)
if("${expected_hash}" STREQUAL "${actual_hash}")
message(
STATUS "File ${dest} already matches the hash. Skipping download.")
return()
else()
message(WARNING "Hash mismatch for ${dest}. Downloading the file again.")
endif()
else()
message(STATUS "File ${dest} not found, downloading without hash check.")
file(
message(STATUS "File ${dest} not found. Downloading.")
endif()
# Download the actual file
file(
DOWNLOAD "${url}" "${dest}"
SHOW_PROGRESS
TIMEOUT 60)
return()
list(GET download_status 0 download_status_code)
list(GET download_status 1 download_error_message)
if(NOT "${download_status_code}" STREQUAL "0")
file(REMOVE "${dest}")
message(FATAL "Failed to download file ${dest} from ${url}. Error: ${download_error_message}")
endif()
endif()
file(READ "${hash_file_temp}" expected_hash)
string(STRIP "${expected_hash}" expected_hash)
if(NOT "${expected_hash}" STREQUAL "")
file(RENAME "${hash_file_temp}" "${hash_file}")
endif()
# Hash file downloaded, now read the hash
file(READ "${hash_file}" expected_hash)
string(STRIP "${expected_hash}" expected_hash) # Remove whitespace around hash
if(EXISTS "${dest}")
# Recheck the hash after downloading
file(SHA256 "${dest}" actual_hash)
if("${expected_hash}" STREQUAL "${actual_hash}")
message(
STATUS "File ${dest} already matches the hash. Skipping download.")
return()
if(NOT "${expected_hash}" STREQUAL "${actual_hash}")
message(
FATAL_ERROR
"Downloaded file ${dest} hash mismatch. Expected: ${expected_hash}, got: ${actual_hash}"
)
else()
message(WARNING "Hash mismatch for ${dest}. Downloading the file again.")
message(STATUS "File ${dest} downloaded and verified successfully.")
endif()
else()
message(STATUS "File ${dest} not found. Downloading.")
endif()
# Download the actual file
file(
DOWNLOAD "${url}" "${dest}"
SHOW_PROGRESS
TIMEOUT 60)
# Recheck the hash after downloading
file(SHA256 "${dest}" actual_hash)
if(NOT "${expected_hash}" STREQUAL "${actual_hash}")
message(
FATAL_ERROR
"Downloaded file ${dest} hash mismatch. Expected: ${expected_hash}, got: ${actual_hash}"
)
else()
message(STATUS "File ${dest} downloaded and verified successfully.")
endif()
endfunction()