Hashes for downloads from multiple urls

In the documentation for including External projects 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?

1 Like

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.

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.

Ok, thanks for the feedback. FileDownload seems a little more flexible but would need more programming to do this.

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.

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

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

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

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.

@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.

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.

1 Like

That sounds a lot like what I did for our superbuild.

2 Likes