cmake: Fix dependency download logic

Previously, if download failure occurred or interrupted by Ctrl-C, the
broken file is not removed. This is true for the first case because
"message(FATAL_ERROR ..." stops cmake and "file(REMOVE ..." is never
reached. After that, if cmake is run second time, SHA256 verification is
skipped and the broken file will be used.

This patch fixes this by using a temporary intermediate file. The file
data is downloaded into a temporary file first, then the temporary file
is atomically renamed to destination.

Error checking of download status is also improved. The if clause now
checks error code against zero more strictly, according to cmake's
documentation.
This commit is contained in:
Zhang Boyang
2026-02-04 01:30:41 +08:00
committed by Ryan Foster
parent 290904c47d
commit 97ee7fa7cb

View File

@@ -153,15 +153,16 @@ function(_check_dependencies)
if(NOT EXISTS "${dependencies_dir}/${file}")
message(STATUS "Downloading ${url}")
file(DOWNLOAD "${url}" "${dependencies_dir}/${file}" STATUS download_status EXPECTED_HASH SHA256=${hash})
file(DOWNLOAD "${url}" "${dependencies_dir}/${file}.tmp" STATUS download_status EXPECTED_HASH SHA256=${hash})
list(GET download_status 0 error_code)
list(GET download_status 1 error_message)
if(error_code GREATER 0)
if(error_code)
file(REMOVE "${dependencies_dir}/${file}.tmp")
message(STATUS "Downloading ${url} - Failure")
message(FATAL_ERROR "Unable to download ${url}, failed with error: ${error_message}")
file(REMOVE "${dependencies_dir}/${file}")
else()
file(RENAME "${dependencies_dir}/${file}.tmp" "${dependencies_dir}/${file}")
message(STATUS "Downloading ${url} - done")
endif()
endif()