Skip to content

Commit dbb957d

Browse files
committed
Update CPM.cmake to version 0.42.0
1 parent 4d85ffb commit dbb957d

File tree

1 file changed

+114
-20
lines changed

1 file changed

+114
-20
lines changed

cmake/CPM.cmake

Lines changed: 114 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ if(NOT COMMAND cpm_message)
4242
endfunction()
4343
endif()
4444

45-
set(CURRENT_CPM_VERSION 0.40.2)
45+
if(DEFINED EXTRACTED_CPM_VERSION)
46+
set(CURRENT_CPM_VERSION "${EXTRACTED_CPM_VERSION}${CPM_DEVELOPMENT}")
47+
else()
48+
set(CURRENT_CPM_VERSION 0.42.0)
49+
endif()
4650

4751
get_filename_component(CPM_CURRENT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" REALPATH)
4852
if(CPM_DIRECTORY)
@@ -162,7 +166,7 @@ set(CPM_SOURCE_CACHE
162166
CACHE PATH "Directory to download CPM dependencies"
163167
)
164168

165-
if(NOT CPM_DONT_UPDATE_MODULE_PATH)
169+
if(NOT CPM_DONT_UPDATE_MODULE_PATH AND NOT DEFINED CMAKE_FIND_PACKAGE_REDIRECTS_DIR)
166170
set(CPM_MODULE_PATH
167171
"${CMAKE_BINARY_DIR}/CPM_modules"
168172
CACHE INTERNAL ""
@@ -198,6 +202,60 @@ function(cpm_package_name_from_git_uri URI RESULT)
198202
endif()
199203
endfunction()
200204

205+
# Find the shortest hash that can be used eg, if origin_hash is
206+
# cccb77ae9609d2768ed80dd42cec54f77b1f1455 the following files will be checked, until one is found
207+
# that is either empty (allowing us to assign origin_hash), or whose contents matches ${origin_hash}
208+
#
209+
# * .../cccb.hash
210+
# * .../cccb77ae.hash
211+
# * .../cccb77ae9609.hash
212+
# * .../cccb77ae9609d276.hash
213+
# * etc
214+
#
215+
# We will be able to use a shorter path with very high probability, but in the (rare) event that the
216+
# first couple characters collide, we will check longer and longer substrings.
217+
function(cpm_get_shortest_hash source_cache_dir origin_hash short_hash_output_var)
218+
# for compatibility with caches populated by a previous version of CPM, check if a directory using
219+
# the full hash already exists
220+
if(EXISTS "${source_cache_dir}/${origin_hash}")
221+
set(${short_hash_output_var}
222+
"${origin_hash}"
223+
PARENT_SCOPE
224+
)
225+
return()
226+
endif()
227+
228+
foreach(len RANGE 4 40 4)
229+
string(SUBSTRING "${origin_hash}" 0 ${len} short_hash)
230+
set(hash_lock ${source_cache_dir}/${short_hash}.lock)
231+
set(hash_fp ${source_cache_dir}/${short_hash}.hash)
232+
# Take a lock, so we don't have a race condition with another instance of cmake. We will release
233+
# this lock when we can, however, if there is an error, we want to ensure it gets released on
234+
# it's own on exit from the function.
235+
file(LOCK ${hash_lock} GUARD FUNCTION)
236+
237+
# Load the contents of .../${short_hash}.hash
238+
file(TOUCH ${hash_fp})
239+
file(READ ${hash_fp} hash_fp_contents)
240+
241+
if(hash_fp_contents STREQUAL "")
242+
# Write the origin hash
243+
file(WRITE ${hash_fp} ${origin_hash})
244+
file(LOCK ${hash_lock} RELEASE)
245+
break()
246+
elseif(hash_fp_contents STREQUAL origin_hash)
247+
file(LOCK ${hash_lock} RELEASE)
248+
break()
249+
else()
250+
file(LOCK ${hash_lock} RELEASE)
251+
endif()
252+
endforeach()
253+
set(${short_hash_output_var}
254+
"${short_hash}"
255+
PARENT_SCOPE
256+
)
257+
endfunction()
258+
201259
# Try to infer package name and version from a url
202260
function(cpm_package_name_and_ver_from_url url outName outVer)
203261
if(url MATCHES "[/\\?]([a-zA-Z0-9_\\.-]+)\\.(tar|tar\\.gz|tar\\.bz2|zip|ZIP)(\\?|/|$)")
@@ -269,10 +327,25 @@ endfunction()
269327
# finding the system library
270328
function(cpm_create_module_file Name)
271329
if(NOT CPM_DONT_UPDATE_MODULE_PATH)
272-
# erase any previous modules
273-
file(WRITE ${CPM_MODULE_PATH}/Find${Name}.cmake
274-
"include(\"${CPM_FILE}\")\n${ARGN}\nset(${Name}_FOUND TRUE)"
275-
)
330+
if(DEFINED CMAKE_FIND_PACKAGE_REDIRECTS_DIR)
331+
# Redirect find_package calls to the CPM package. This is what FetchContent does when you set
332+
# OVERRIDE_FIND_PACKAGE. The CMAKE_FIND_PACKAGE_REDIRECTS_DIR works for find_package in CONFIG
333+
# mode, unlike the Find${Name}.cmake fallback. CMAKE_FIND_PACKAGE_REDIRECTS_DIR is not defined
334+
# in script mode, or in CMake < 3.24.
335+
# https://cmake.org/cmake/help/latest/module/FetchContent.html#fetchcontent-find-package-integration-examples
336+
string(TOLOWER ${Name} NameLower)
337+
file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/${NameLower}-config.cmake
338+
"include(\"\${CMAKE_CURRENT_LIST_DIR}/${NameLower}-extra.cmake\" OPTIONAL)\n"
339+
"include(\"\${CMAKE_CURRENT_LIST_DIR}/${Name}Extra.cmake\" OPTIONAL)\n"
340+
)
341+
file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/${NameLower}-config-version.cmake
342+
"set(PACKAGE_VERSION_COMPATIBLE TRUE)\n" "set(PACKAGE_VERSION_EXACT TRUE)\n"
343+
)
344+
else()
345+
file(WRITE ${CPM_MODULE_PATH}/Find${Name}.cmake
346+
"include(\"${CPM_FILE}\")\n${ARGN}\nset(${Name}_FOUND TRUE)"
347+
)
348+
endif()
276349
endif()
277350
endfunction()
278351

@@ -475,7 +548,7 @@ function(cpm_add_patches)
475548

476549
# Find the patch program.
477550
find_program(PATCH_EXECUTABLE patch)
478-
if(WIN32 AND NOT PATCH_EXECUTABLE)
551+
if(CMAKE_HOST_WIN32 AND NOT PATCH_EXECUTABLE)
479552
# The Windows git executable is distributed with patch.exe. Find the path to the executable, if
480553
# it exists, then search `../usr/bin` and `../../usr/bin` for patch.exe.
481554
find_package(Git QUIET)
@@ -575,14 +648,6 @@ endfunction()
575648
function(CPMAddPackage)
576649
cpm_set_policies()
577650

578-
list(LENGTH ARGN argnLength)
579-
if(argnLength EQUAL 1)
580-
cpm_parse_add_package_single_arg("${ARGN}" ARGN)
581-
582-
# The shorthand syntax implies EXCLUDE_FROM_ALL and SYSTEM
583-
set(ARGN "${ARGN};EXCLUDE_FROM_ALL;YES;SYSTEM;YES;")
584-
endif()
585-
586651
set(oneValueArgs
587652
NAME
588653
FORCE
@@ -605,10 +670,26 @@ function(CPMAddPackage)
605670

606671
set(multiValueArgs URL OPTIONS DOWNLOAD_COMMAND PATCHES)
607672

673+
list(LENGTH ARGN argnLength)
674+
675+
# Parse single shorthand argument
676+
if(argnLength EQUAL 1)
677+
cpm_parse_add_package_single_arg("${ARGN}" ARGN)
678+
679+
# The shorthand syntax implies EXCLUDE_FROM_ALL and SYSTEM
680+
set(ARGN "${ARGN};EXCLUDE_FROM_ALL;YES;SYSTEM;YES;")
681+
682+
# Parse URI shorthand argument
683+
elseif(argnLength GREATER 1 AND "${ARGV0}" STREQUAL "URI")
684+
list(REMOVE_AT ARGN 0 1) # remove "URI gh:<...>@version#tag"
685+
cpm_parse_add_package_single_arg("${ARGV1}" ARGV0)
686+
687+
set(ARGN "${ARGV0};EXCLUDE_FROM_ALL;YES;SYSTEM;YES;${ARGN}")
688+
endif()
689+
608690
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}")
609691

610692
# Set default values for arguments
611-
612693
if(NOT DEFINED CPM_ARGS_VERSION)
613694
if(DEFINED CPM_ARGS_GIT_TAG)
614695
cpm_get_version_from_git_tag("${CPM_ARGS_GIT_TAG}" CPM_ARGS_VERSION)
@@ -779,9 +860,19 @@ function(CPMAddPackage)
779860
set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${CPM_ARGS_CUSTOM_CACHE_KEY})
780861
elseif(CPM_USE_NAMED_CACHE_DIRECTORIES)
781862
string(SHA1 origin_hash "${origin_parameters};NEW_CACHE_STRUCTURE_TAG")
863+
cpm_get_shortest_hash(
864+
"${CPM_SOURCE_CACHE}/${lower_case_name}" # source cache directory
865+
"${origin_hash}" # Input hash
866+
origin_hash # Computed hash
867+
)
782868
set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${origin_hash}/${CPM_ARGS_NAME})
783869
else()
784870
string(SHA1 origin_hash "${origin_parameters}")
871+
cpm_get_shortest_hash(
872+
"${CPM_SOURCE_CACHE}/${lower_case_name}" # source cache directory
873+
"${origin_hash}" # Input hash
874+
origin_hash # Computed hash
875+
)
785876
set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${origin_hash})
786877
endif()
787878
# Expand `download_directory` relative path. This is important because EXISTS doesn't work for
@@ -848,7 +939,9 @@ function(CPMAddPackage)
848939
endif()
849940
endif()
850941

851-
cpm_create_module_file(${CPM_ARGS_NAME} "CPMAddPackage(\"${ARGN}\")")
942+
if(NOT "${DOWNLOAD_ONLY}")
943+
cpm_create_module_file(${CPM_ARGS_NAME} "CPMAddPackage(\"${ARGN}\")")
944+
endif()
852945

853946
if(CPM_PACKAGE_LOCK_ENABLED)
854947
if((CPM_ARGS_VERSION AND NOT CPM_ARGS_SOURCE_DIR) OR CPM_INCLUDE_ALL_IN_PACKAGE_LOCK)
@@ -869,8 +962,9 @@ function(CPMAddPackage)
869962
# Calling FetchContent_MakeAvailable will then internally forward these options to
870963
# add_subdirectory. Up until these changes, we had to call FetchContent_Populate and
871964
# add_subdirectory separately, which is no longer necessary and has been deprecated as of 3.30.
965+
# A Bug in CMake prevents us to use the non-deprecated functions until 3.30.3.
872966
set(fetchContentDeclareExtraArgs "")
873-
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28.0")
967+
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.30.3")
874968
if(${CPM_ARGS_EXCLUDE_FROM_ALL})
875969
list(APPEND fetchContentDeclareExtraArgs EXCLUDE_FROM_ALL)
876970
endif()
@@ -896,7 +990,7 @@ function(CPMAddPackage)
896990
if(CPM_SOURCE_CACHE AND download_directory)
897991
file(LOCK ${download_directory}/../cmake.lock RELEASE)
898992
endif()
899-
if(${populated} AND ${CMAKE_VERSION} VERSION_LESS "3.28.0")
993+
if(${populated} AND ${CMAKE_VERSION} VERSION_LESS "3.30.3")
900994
cpm_add_subdirectory(
901995
"${CPM_ARGS_NAME}"
902996
"${DOWNLOAD_ONLY}"
@@ -1098,7 +1192,7 @@ function(cpm_fetch_package PACKAGE DOWNLOAD_ONLY populated)
10981192
string(TOLOWER "${PACKAGE}" lower_case_name)
10991193

11001194
if(NOT ${lower_case_name}_POPULATED)
1101-
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28.0")
1195+
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.30.3")
11021196
if(DOWNLOAD_ONLY)
11031197
# MakeAvailable will call add_subdirectory internally which is not what we want when
11041198
# DOWNLOAD_ONLY is set. Populate will only download the dependency without adding it to the

0 commit comments

Comments
 (0)