On usage of ExternalData module

Hi, I’m trying to fetch an archive file from the remote and want to put it on source directory at build time. So tried the following code:

  if(CHIP8_DOWNLOAD_ROMS)                                                                                       
      include(ExternalData)                                                                                     
      # https://archive.org/download/Chip-8RomsThatAreInThePublicDomain/c8games.zip                                
      set(ExternalData_URL_TEMPLATES                                                                               
          "${CMAKE_SOURCE_DIR}/%(algo)/%(hash)"                                                                    
          "https://archive.org/download/Chip-8RomsThatAreInThePublicDomain/%(algo)/%(hash)")                       
      ExternalData_Expand_Arguments(                                                                               
          target                                                                                                   
          roms                                                                                                     
          DATA{c8games.zip})                                                                                       
                                                                                                                   
     ExternalData_Add_Target(target)                                                                               
                                                                                                                   
     add_custom_command(TARGET chip8 POST_BUILD                                                                    
      COMMAND ${CMAKE_COMMAND} -E make_directory  $<TARGET_FILE_DIR:chip8>/roms                                    
      COMMAND ${CMAKE_COMMAND} -E copy ${c8games} $<TARGET_FILE_DIR:chip8>/roms                                    
      COMMAND ${CMAKE_COMMAND} -E chdir  $<TARGET_FILE_DIR:chip8>/roms                                          
      COMMAND ${CMAKE_COMMAND} -E tar x ${c8games})                                                                                                                                           
  endif() 

These are not a part of the project so I thought it’s better to give client an option to fetch them.
I downloaded the files on the link and create SHA1 sum using command line utility:

$ sha1sum c8games.zip

And put the checksum result on top level directory: c8games.zip.sha1. This is described by the ExternalData module documentation. But when I run:

$ cmake -DCHIP8_DOWNLOAD_ROMS=On -S . -B build
$ cmake --build build 

I got the following output:

[ 33%] Generating /home/adem/github/chip-8/build/c8games.zip
-- Fetching "/home/adem/github/chip-8/SHA1/e50d2923c2b3de084eaa0bc055832f6e27d0b5ec"
-- Fetching "https://archive.org/download/Chip-8RomsThatAreInThePublicDomain/SHA1/e50d2923c2b3de084eaa0bc055832f6e27d0b5ec"
CMake Error at /usr/local/share/cmake-3.15/Modules/ExternalData.cmake:1121 (message):
  

  Object SHA1=e50d2923c2b3de084eaa0bc055832f6e27d0b5ec not found at:

    /home/adem/github/chip-8/SHA1/e50d2923c2b3de084eaa0bc055832f6e27d0b5ec ("URL using bad/illegal format or missing URL")
    https://archive.org/download/Chip-8RomsThatAreInThePublicDomain/SHA1/e50d2923c2b3de084eaa0bc055832f6e27d0b5ec ("Unsupported protocol")


make[2]: *** [CMakeFiles/target.dir/build.make:61: c8games.zip-hash-stamp] Error 1
make[1]: *** [CMakeFiles/Makefile2:77: CMakeFiles/target.dir/all] Error 2
make: *** [Makefile:84: all] Error 2

I wonder what I’m doing wrong. Any pointer is really appreciated.

/home/adem/github/chip-8/SHA1/e50d2923c2b3de084eaa0bc055832f6e27d0b5ec ("URL using bad/illegal format or missing URL")

Based on the example in https://cmake.org/cmake/help/latest/module/ExternalData.html#introduction, URLs should have a protocol. So it should be "file://${CMAKE_SOURCE_DIR}/%(algo)/%(hash)"

https://archive.org/download/Chip-8RomsThatAreInThePublicDomain/SHA1/e50d2923c2b3de084eaa0bc055832f6e27d0b5ec ("Unsupported protocol")

It seems that the HTTPS protocol is not supported. I guess you could try HTTP.

Thanks for the reply… But now I tried with the following:

 if(CHIP8_DOWNLOAD_ROMS)                                                                                       
      include(ExternalData)                                                                                     
      # https://archive.org/download/Chip-8RomsThatAreInThePublicDomain/c8games.zip                             
      set(ExternalData_URL_TEMPLATES                                                                            
          "file://${CMAKE_SOURCE_DIR}/%(algo)/%(hash)"                                                                                                        
          "http://archive.org/download/Chip-8RomsThatAreInThePublicDomain/%(algo)/%(hash)")                     
      ExternalData_Expand_Arguments(                                                                            
          target                                                                                                
          roms                                                                                                  
          DATA{c8games.zip})                                                                                    
                                                                                                                
     ExternalData_Add_Target(target)                                                                            
                                                                                                                
                                                                                                                
     #add_custom_command(TARGET chip8 POST_BUILD                                                                
     # COMMAND ${CMAKE_COMMAND} -E make_directory  $<TARGET_FILE_DIR:chip8>/roms                                
     # COMMAND ${CMAKE_COMMAND} -E copy ${c8games} $<TARGET_FILE_DIR:chip8>/roms                                
     # COMMAND ${CMAKE_COMMAND} -E chdir  $<TARGET_FILE_DIR:chip8>/roms                                        
     # COMMAND ${CMAKE_COMMAND} -E tar x ${c8games})                                                            
  endif()  

and get:

$ cmake --build build
[ 66%] Built target chip8
[100%] Generating /home/adem/github/chip-8/build/c8games.zip
-- Fetching "file:///home/adem/github/chip-8/SHA1/e50d2923c2b3de084eaa0bc055832f6e27d0b5ec"
-- Fetching "http://archive.org/download/Chip-8RomsThatAreInThePublicDomain/SHA1/e50d2923c2b3de084eaa0bc055832f6e27d0b5ec"
CMake Error at /usr/local/share/cmake-3.15/Modules/ExternalData.cmake:1121 (message):
  

  Object SHA1=e50d2923c2b3de084eaa0bc055832f6e27d0b5ec not found at:

    file:///home/adem/github/chip-8/SHA1/e50d2923c2b3de084eaa0bc055832f6e27d0b5ec ("Couldn't read a file:// file")
    http://archive.org/download/Chip-8RomsThatAreInThePublicDomain/SHA1/e50d2923c2b3de084eaa0bc055832f6e27d0b5ec ("HTTP response code said error")

make[2]: *** [CMakeFiles/target.dir/build.make:61: c8games.zip-hash-stamp] Error 1
make[1]: *** [CMakeFiles/Makefile2:109: CMakeFiles/target.dir/all] Error 2
make: *** [Makefile:106: all] Error 2

Hmm. It may be easier to (ab)use ExternalProject for this.

ExternalProject_Add(pdroms
  URL ...
  SOURCE_DIR "extraction/dir"
  BUILD_IN_SOURCE 1 # avoid creation of a build directory
  CONFIGURE_COMMAND ""
  BUILD_COMMAND ""
  INSTALL_COMMAND "")
1 Like