# Hashes for downloads from multiple urls

**URL:** https://discourse.cmake.org/t/hashes-for-downloads-from-multiple-urls/4199
**Category:** Usage
**Created:** [October 4, 2021, 7:04am UTC](https://discourse.cmake.org/t/hashes-for-downloads-from-multiple-urls/4199 "2021-10-04T07:04:16Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![bcmkakme](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bcmkakme/32/1849_2.png) [@bcmkakme](https://discourse.cmake.org/u/bcmkakme)
#### Post date: [October 4, 2021, 7:04am UTC](https://discourse.cmake.org/t/hashes-for-downloads-from-multiple-urls/4199/1 "2021-10-04T07:04:16Z")

</div>

In the documentation for including External projects [https://cmake.org/cmake/help/latest/module/ExternalProject.html](https://cmake.org/cmake/help/latest/module/ExternalProject.html) from 3.17 it is possible to have multiple URLs to attempt to download from, it may be the case that the code at each URL is different, so will have a different hash, even if it contains the necessary functionality to work. Is there a way to check whether a download succeeded and if it failed, use a different URL with a different hash?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [October 4, 2021, 4:14pm UTC](https://discourse.cmake.org/t/hashes-for-downloads-from-multiple-urls/4199/2 "2021-10-04T16:14:12Z")

</div>

I think the only thing there is to not verify. It seems like it’s intended to be multiple locations for the same content. Maybe support could be added, but I don’t think it’s high on anyone’s list unless someone else writes up a patchset.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [October 4, 2021, 8:25pm UTC](https://discourse.cmake.org/t/hashes-for-downloads-from-multiple-urls/4199/3 "2021-10-04T20:25:39Z")

</div>

I would question downloading different files from different locations within the one `ExternalProject_Add()` command. That is getting outside the scope of what that command aims to support and starts to open up corner cases that, personally, I’d much prefer to avoid. As Ben says, if you really want to go down that path, you’ll have to give up on having the command verify the downloaded content with a hash.

---

<div class="post-metadata">

### Author: ![bcmkakme](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bcmkakme/32/1849_2.png) [@bcmkakme](https://discourse.cmake.org/u/bcmkakme)
#### Post date: [October 5, 2021, 5:31am UTC](https://discourse.cmake.org/t/hashes-for-downloads-from-multiple-urls/4199/4 "2021-10-05T05:31:29Z")

</div>

Ok, thanks for the feedback. [FileDownload](https://cmake.org/cmake/help/latest/command/file.html#transfer) seems a little more flexible but would need more programming to do this.

---

<div class="post-metadata">

### Author: ![CraigEmteq](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craigemteq/32/1229_2.png) [@CraigEmteq](https://discourse.cmake.org/u/CraigEmteq)
#### Post date: [October 6, 2021, 8:29am UTC](https://discourse.cmake.org/t/hashes-for-downloads-from-multiple-urls/4199/5 "2021-10-06T08:29:09Z")

</div>

Could it not be possible to detect that the first `ExternalProject_Add` failed and instead just have a chain of fallback calls to the function somehow? That way `ExternalProject_Add` remains its simple self but allows extending to the OP issue.

e.g.

```auto
ExternalProject_Add( Atarget ShaA..)
if ( ATarget_NOT_FOUND )
    ExternalProject_Add( Atarget ShaB..)
if ( ATarget_NOT_FOUND )
    ExternalProject_Add( Atarget ShaC..)

```

---

<div class="post-metadata">

### Author: ![bcmkakme](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bcmkakme/32/1849_2.png) [@bcmkakme](https://discourse.cmake.org/u/bcmkakme)
#### Post date: [October 6, 2021, 9:42am UTC](https://discourse.cmake.org/t/hashes-for-downloads-from-multiple-urls/4199/6 "2021-10-06T09:42:28Z")

</div>

Thanks for the suggestion. Something similar to what is at:

> <https://github.com/Kitware/CMake/blob/master/Tests/Contracts/Trilinos/CMakeLists.txt>

Can be done, check if download occurred and if not, use another location.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [October 6, 2021, 12:15pm UTC](https://discourse.cmake.org/t/hashes-for-downloads-from-multiple-urls/4199/7 "2021-10-06T12:15:40Z")

</div>

I don’t see how this would work as “download not found” is a build-time determination and the configure code could not possibly know this.

---

<div class="post-metadata">

### Author: ![CraigEmteq](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craigemteq/32/1229_2.png) [@CraigEmteq](https://discourse.cmake.org/u/CraigEmteq)
#### Post date: [October 6, 2021, 12:29pm UTC](https://discourse.cmake.org/t/hashes-for-downloads-from-multiple-urls/4199/8 "2021-10-06T12:29:17Z")

</div>

@ben.boeckel True, it is possible the simple logic won’t be viable with ExternalProject\_Add.

FetchContent\_MakeAvailable may not directly fit the intended use-case, however this can be used to download at configure time. However when that fails the configure is aborted I seem to recall.

I do feel the solution @craig.scott is the best option for now.

---

<div class="post-metadata">

### Author: ![codeling](https://discourse.cmake.org/user_avatar/discourse.cmake.org/codeling/32/1700_2.png) [@codeling](https://discourse.cmake.org/u/codeling)
#### Post date: [October 6, 2021, 3:06pm UTC](https://discourse.cmake.org/t/hashes-for-downloads-from-multiple-urls/4199/9 "2021-10-06T15:06:22Z")

</div>

Something that I have experimented with for supporting multiple versions of external libraries is having a drop down list (via some CACHE variable xyz and `set_property(CACHE xyz PROPERTY STRINGS a b c)` in which the user choses the option suitable for him; then the CMakeLists sets the corresponding URL and hash sum, based on the user choice, that subsequently are used in the ExternalProject\_Add call.

Of course this doesn’t allow for automatic fallback (the user would have to switch to another option manually), but it would enable to have a hash sum check and still an option to have multiple different sources.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [October 6, 2021, 4:51pm UTC](https://discourse.cmake.org/t/hashes-for-downloads-from-multiple-urls/4199/10 "2021-10-06T16:51:18Z")

</div>

That sounds a lot like what I did for [our superbuild](https://gitlab.kitware.com/paraview/common-superbuild/-/blob/056eecea1e4d15e433c70b939ae615a0c255463a/cmake/SuperbuildRevisionMacros.cmake#L115).
