FILE(DOWNLOAD....) How to get more informative error messages

As part of our project we generate a CMake file with these contents:

# -----------------------------------------------------------------------
cmake_policy(SET CMP0012 NEW)
cmake_policy(SET CMP0054 NEW)

# --------------------------------------------------------------------------------------------------
# STARTING 6_5_test_data_1.tar.gz
# Download, Decompress, and possibly copy data archive
# message(STATUS "[DATA DOWNLOAD] 6_5_test_data_1.tar.gz")
# --------------------------------------------------------------------------------------------------
string(TIMESTAMP time_stamp_start %s)
file(DOWNLOAD https://github.com/bluequartzsoftware/simplnx/releases/download/Data_Archive/6_5_test_data_1.tar.gz
              "/Users/mjackson/Workspace1/DREAM3DNX/../DREAM3D_Data/TestFiles/6_5_test_data_1.tar.gz"
              EXPECTED_HASH SHA512=6e21118a882c6a0cc54341eec8928b89ee84ac3a41b1d5b534193f4fabcb49c363db22028055622ad777787be0163cf5525e6c548c11c2c369748feb23031651
              # SHOW_PROGRESS
              STATUS result
              )
string(TIMESTAMP time_stamp_end %s)
list(GET result 1 status)
string(REPLACE "\"" "" status "${status}")

if("${status}" STREQUAL "No error")
  math(EXPR time_diff "${time_stamp_end} - ${time_stamp_start}" OUTPUT_FORMAT DECIMAL)      # value is set to "1000"
  file(SIZE "/Users/mjackson/Workspace1/DREAM3DNX/../DREAM3D_Data/TestFiles/6_5_test_data_1.tar.gz" file_size)
  if(NOT "${time_diff}" STREQUAL "0")
    math(EXPR bandwidth "${file_size} / ${time_diff}" OUTPUT_FORMAT DECIMAL)      # value is set to "1000"
    message(STATUS "6_5_test_data_1.tar.gz Download Complete: ${bandwidth} bytes/sec")
  else()
    message(STATUS "6_5_test_data_1.tar.gz Download Complete")
  endif()
endif()

which is basically repeated for about 50 other files. The issue is that when there is an error we get the following output during the build:

CMake Error at simplnx_fetch_remote_files.cmake:149 (file):
  file DOWNLOAD cannot compute hash on failed download

    status: [28;"Timeout was reached"]

which is sort of helpful. Obviously, I can go into the file and look at that line number and then get which file was the issue. But if this is on a CI machine, I don’t have the luxury. Is there any way to entice the “FILE” command to give a more detailed error message? We are on CMake 3.26.x currently.

Looking at the docs for the “FILE(DOWNLOAD…)” command I see a “LOG” option… except that I can’t even print what gets stored in that variable because CMake errors out before the next line of code is executed (Which would be my message(STATUS “”) line).

I guess I could use “SHOW_PROGRESS” but that is going to get awful messy with that number of files.

I could also do at message(STATUS "Download Started"..) but this is also starting to print a lot of output when it isn’t needed in most cases.

What I’m asking is how to get CMake to print an error like:

CMake Error at simplnx_fetch_remote_files.cmake:149 (file):
  file DOWNLOAD cannot compute hash on failed download
   URL: https://github.com/bluequartzsoftware/simplnx/releases/download/Data_Archive/6_5_test_data_1.tar.gz
  Result: time out

Thoughts?

Try a newer CMake. Even for v3.25 the error message looks like this:

CMake Error at down.cmake:1 (file):
  file DOWNLOAD HASH mismatch

    for file: [ubuntu-24.04-desktop-amd64.iso]
      expected hash: [123]
        actual hash: [a782772aab97d3ca46cd5e0cae9c3de9054a7779a1daaa2511557a36b2fbe840a7d15cec5057947ac076d4fca8a1f6aa0347a342c0c6ffffc078023e3a2aee13]
             status: [28;"Timeout was reached"]

Although I would have expected the command does not error out, if a STATUS variable is used.

We are using CMake 3.26.x for the configuration. Maybe I’m just not using the FILE(DOWNLOAD …) command correctly?

I have no experience with file(DOWNLOAD) myself. But this is the script I executed with cmake -P:

file(DOWNLOAD
  "https://releases.ubuntu.com/24.04/ubuntu-24.04-desktop-amd64.iso"
  "ubuntu-24.04-desktop-amd64.iso"
  TIMEOUT 1
  EXPECTED_HASH SHA512=123
  STATUS status
)
message(STATUS ${status})

I just used a big file with a very small TIMEOUT value to force the error message.
Without the TIMEOUT option, I don’t know why you get this error message at all.

Looking at the source code, this was changed in CMake v3.26 in MR7888.
That MR looks valid, as it is useless to check the hash on an incomplete download.

I guess it makes sense, to print the URL for every file(DOWNLOAD) or file(UPLOAD) connection related error. And maybe the filename for every file related error. Or simply both.
You should consider creating a MR, and/or an issue to clarify the matter with the maintainers.