diff options
author | Craig Scott <craig.scott@crascit.com> | 2022-07-29 10:58:08 (GMT) |
---|---|---|
committer | Craig Scott <craig.scott@crascit.com> | 2022-07-29 10:58:08 (GMT) |
commit | fd95769ccf9e86218ec021083edc0335757122d6 (patch) | |
tree | 5ddee4dc6268a319247ce1c7b4af5d56c79aa702 /Modules/FetchContent.cmake | |
parent | 5ead1d0a257e352c35ac63b78f4884058b17b8f9 (diff) | |
download | CMake-fd95769ccf9e86218ec021083edc0335757122d6.zip CMake-fd95769ccf9e86218ec021083edc0335757122d6.tar.gz CMake-fd95769ccf9e86218ec021083edc0335757122d6.tar.bz2 |
FetchContent: Restore support for multiple URL values
In c2044fdf3f (FetchContent: Respect the CMP0135 policy setting,
2022-06-02), the URL keyword was wrongly assumed to only have
a single value. Multiple URL values are allowed if they are all
non-local. Rework the logic to remove that incorrect assumption
and handle both single and multi-value URL combinations.
Fixes: #23792
Diffstat (limited to 'Modules/FetchContent.cmake')
-rw-r--r-- | Modules/FetchContent.cmake | 71 |
1 files changed, 42 insertions, 29 deletions
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index df40c85..27070c0 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -1189,19 +1189,18 @@ function(FetchContent_Declare contentName) ) endif() - set(options "") + # Because we are only looking for a subset of the supported keywords, we + # cannot check for multi-value arguments with this method. We will have to + # handle the URL keyword differently. set(oneValueArgs SVN_REPOSITORY DOWNLOAD_NO_EXTRACT DOWNLOAD_EXTRACT_TIMESTAMP - URL BINARY_DIR SOURCE_DIR ) - set(multiValueArgs "") - cmake_parse_arguments(PARSE_ARGV 1 ARG - "${options}" "${oneValueArgs}" "${multiValueArgs}") + cmake_parse_arguments(PARSE_ARGV 1 ARG "" "${oneValueArgs}" "") string(TOLOWER ${contentName} contentNameLower) @@ -1230,31 +1229,45 @@ function(FetchContent_Declare contentName) # explicitly set the relevant option if not already provided. The condition # here is essentially an abbreviated version of the logic in # ExternalProject's _ep_add_download_command() function. - if(ARG_URL AND - NOT IS_DIRECTORY "${ARG_URL}" AND - NOT ARG_DOWNLOAD_NO_EXTRACT AND + if(NOT ARG_DOWNLOAD_NO_EXTRACT AND NOT DEFINED ARG_DOWNLOAD_EXTRACT_TIMESTAMP) - cmake_policy(GET CMP0135 _FETCHCONTENT_CMP0135 - PARENT_SCOPE # undocumented, do not use outside of CMake - ) - if(_FETCHCONTENT_CMP0135 STREQUAL "") - message(AUTHOR_WARNING - "The DOWNLOAD_EXTRACT_TIMESTAMP option was not given and policy " - "CMP0135 is not set. The policy's OLD behavior will be used. " - "When using a URL download, the timestamps of extracted files " - "should preferably be that of the time of extraction, otherwise " - "code that depends on the extracted contents might not be " - "rebuilt if the URL changes. The OLD behavior preserves the " - "timestamps from the archive instead, but this is usually not " - "what you want. Update your project to the NEW behavior or " - "specify the DOWNLOAD_EXTRACT_TIMESTAMP option with a value of " - "true to avoid this robustness issue." - ) - set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP TRUE) - elseif(_FETCHCONTENT_CMP0135 STREQUAL "NEW") - set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP FALSE) - else() - set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP TRUE) + list(FIND ARGN URL urlIndex) + if(urlIndex GREATER_EQUAL 0) + math(EXPR urlIndex "${urlIndex} + 1") + list(LENGTH ARGN numArgs) + if(urlIndex GREATER_EQUAL numArgs) + message(FATAL_ERROR + "URL keyword needs to be followed by at least one URL" + ) + endif() + # If we have multiple URLs, none of them are allowed to be local paths. + # Therefore, we can test just the first URL, and if it is non-local, so + # will be the others if there are more. + list(GET ARGN ${urlIndex} firstUrl) + if(NOT IS_DIRECTORY "${firstUrl}") + cmake_policy(GET CMP0135 _FETCHCONTENT_CMP0135 + PARENT_SCOPE # undocumented, do not use outside of CMake + ) + if(_FETCHCONTENT_CMP0135 STREQUAL "") + message(AUTHOR_WARNING + "The DOWNLOAD_EXTRACT_TIMESTAMP option was not given and policy " + "CMP0135 is not set. The policy's OLD behavior will be used. " + "When using a URL download, the timestamps of extracted files " + "should preferably be that of the time of extraction, otherwise " + "code that depends on the extracted contents might not be " + "rebuilt if the URL changes. The OLD behavior preserves the " + "timestamps from the archive instead, but this is usually not " + "what you want. Update your project to the NEW behavior or " + "specify the DOWNLOAD_EXTRACT_TIMESTAMP option with a value of " + "true to avoid this robustness issue." + ) + set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP TRUE) + elseif(_FETCHCONTENT_CMP0135 STREQUAL "NEW") + set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP FALSE) + else() + set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP TRUE) + endif() + endif() endif() endif() |