summaryrefslogtreecommitdiff
path: root/Modules/FetchContent.cmake
diff options
context:
space:
mode:
authorCraig Scott <craig.scott@crascit.com>2022-07-29 20:58:08 +1000
committerCraig Scott <craig.scott@crascit.com>2022-07-29 20:58:08 +1000
commitfd95769ccf9e86218ec021083edc0335757122d6 (patch)
tree5ddee4dc6268a319247ce1c7b4af5d56c79aa702 /Modules/FetchContent.cmake
parent5ead1d0a257e352c35ac63b78f4884058b17b8f9 (diff)
downloadcmake-fd95769ccf9e86218ec021083edc0335757122d6.tar.gz
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.cmake71
1 files changed, 42 insertions, 29 deletions
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index df40c859d4..27070c05a4 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()