Hello there,

I try to continue the work from André.
With the attached patch it is possible to use a list of URLs
but it is still limited to a single path.

I think for a mix of pathes/URLs we need to move a lot of code
from ExternalProject.cmake into ExternalProject-download.cmake.
Maybe it is good to realize this in a new ticket/commit?

Best regards
    Lars Schmertmann

From 036b3cb1a459befe7c0917f98c53ec0f176d2a8e Mon Sep 17 00:00:00 2001
From: Lars Schmertmann <lars.schmertm...@governikus.de>
Date: Tue, 12 Jul 2016 16:53:36 +0200
Subject: [PATCH] Add support for multiple/alternative URLs

Now it is possible to pass multiple URLs as a list
that will be tried in and foreach(). So it will
try next URL if the previous failed.
---
 Modules/ExternalProject-download.cmake.in | 84 +++++++++++++++++--------------
 Modules/ExternalProject.cmake             | 17 ++++++-
 2 files changed, 61 insertions(+), 40 deletions(-)

diff --git a/Modules/ExternalProject-download.cmake.in b/Modules/ExternalProject-download.cmake.in
index 5b73cd8..91d74e0 100644
--- a/Modules/ExternalProject-download.cmake.in
+++ b/Modules/ExternalProject-download.cmake.in
@@ -114,48 +114,56 @@ endif()
 
 set(retry_number 5)
 
+message(STATUS "Downloading...
+   dst='@LOCAL@'
+   timeout='@TIMEOUT_MSG@'"
+)
+
 foreach(i RANGE ${retry_number})
   sleep_before_download(${i})
 
-  message(STATUS "downloading...
-       src='@REMOTE@'
-       dst='@LOCAL@'
-       timeout='@TIMEOUT_MSG@'")
-
-  @TLS_VERIFY_CODE@
-  @TLS_CAINFO_CODE@
-
-  file(
-      DOWNLOAD
-      "@REMOTE@" "@LOCAL@"
-      @SHOW_PROGRESS@
-      @TIMEOUT_ARGS@
-      STATUS status
-      LOG log
-  )
-
-  list(GET status 0 status_code)
-  list(GET status 1 status_string)
-
-  if(status_code EQUAL 0)
-    check_file_hash(has_hash hash_is_good)
-    if(has_hash AND NOT hash_is_good)
-      message(STATUS "Hash mismatch, removing...")
-      file(REMOVE "@LOCAL@")
+  foreach(url @REMOTE@)
+    message(STATUS "Using src='${url}'")
+
+    @TLS_VERIFY_CODE@
+    @TLS_CAINFO_CODE@
+
+    file(
+        DOWNLOAD
+        "${url}" "@LOCAL@"
+        @SHOW_PROGRESS@
+        @TIMEOUT_ARGS@
+        STATUS status
+        LOG log
+    )
+
+    list(GET status 0 status_code)
+    list(GET status 1 status_string)
+
+    if(status_code EQUAL 0)
+      check_file_hash(has_hash hash_is_good)
+      if(has_hash AND NOT hash_is_good)
+        message(STATUS "Hash mismatch, removing...")
+        file(REMOVE "@LOCAL@")
+      else()
+        message(STATUS "Downloading... done")
+        return()
+      endif()
     else()
-      message(STATUS "Downloading... done")
-      return()
+      string(APPEND logFailedURLs "error: downloading '${url}' failed
+       status_code: ${status_code}
+       status_string: ${status_string}
+       log:
+       --- LOG BEGIN ---
+       ${log}
+       --- LOG END ---
+       "
+      )
     endif()
-  else()
-    message("error: downloading '@REMOTE@' failed
-  status_code: ${status_code}
-  status_string: ${status_string}
-  log:
-  --- LOG BEGIN ---
-  ${log}
-  --- LOG END ---"
-    )
-  endif()
+  endforeach()
 endforeach()
 
-message(FATAL_ERROR "Downloading failed")
+message(FATAL_ERROR "Each download failed!
+  ${logFailedURLs}
+  "
+)
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 3686fb6..749d5ea 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -69,8 +69,8 @@ Create custom targets to build projects in external trees
     URL of mercurial repo
   ``HG_TAG <tag>``
     Mercurial branch name, commit id or tag
-  ``URL /.../src.tgz``
-    Full path or URL of source
+  ``URL /.../src.tgz </.../src.tgz>``
+    Full path or URL(s) of source. Multiple URLs are allowed as mirrors.
   ``URL_HASH ALGO=value``
     Hash of file at URL
   ``URL_MD5 md5``
@@ -1861,6 +1861,19 @@ function(_ep_add_download_command name)
       @ONLY
       )
     list(APPEND depends ${stamp_dir}/${name}-urlinfo.txt)
+
+    list(LENGTH url url_list_length)
+    if(NOT "${url_list_length}" STREQUAL "1")
+      foreach(entry ${url})
+        if(NOT "${entry}" MATCHES "^[a-z]+://")
+          message(FATAL_ERROR "At least one entry of URL is a path (invalid in a list)")
+        endif()
+      endforeach()
+      if("x${fname}" STREQUAL "x")
+        list(GET url 0 fname)
+      endif()
+    endif()
+
     if(IS_DIRECTORY "${url}")
       get_filename_component(abs_dir "${url}" ABSOLUTE)
       set(comment "Performing download step (DIR copy) for '${name}'")
-- 
2.9.0

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers

Reply via email to