@@ -42,7 +42,11 @@ if(NOT COMMAND cpm_message)
42
42
endfunction ()
43
43
endif ()
44
44
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 ()
46
50
47
51
get_filename_component (CPM_CURRENT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR} " REALPATH )
48
52
if (CPM_DIRECTORY )
@@ -162,7 +166,7 @@ set(CPM_SOURCE_CACHE
162
166
CACHE PATH "Directory to download CPM dependencies"
163
167
)
164
168
165
- if (NOT CPM_DONT_UPDATE_MODULE_PATH )
169
+ if (NOT CPM_DONT_UPDATE_MODULE_PATH AND NOT DEFINED CMAKE_FIND_PACKAGE_REDIRECTS_DIR )
166
170
set (CPM_MODULE_PATH
167
171
"${CMAKE_BINARY_DIR} /CPM_modules"
168
172
CACHE INTERNAL ""
@@ -198,6 +202,60 @@ function(cpm_package_name_from_git_uri URI RESULT)
198
202
endif ()
199
203
endfunction ()
200
204
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
+
201
259
# Try to infer package name and version from a url
202
260
function (cpm_package_name_and_ver_from_url url outName outVer )
203
261
if (url MATCHES "[/\\ ?]([a-zA-Z0-9_\\ .-]+)\\ .(tar|tar\\ .gz|tar\\ .bz2|zip|ZIP)(\\ ?|/|$)" )
@@ -269,10 +327,25 @@ endfunction()
269
327
# finding the system library
270
328
function (cpm_create_module_file Name )
271
329
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} \n set(${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} \n set(${Name} _FOUND TRUE)"
347
+ )
348
+ endif ()
276
349
endif ()
277
350
endfunction ()
278
351
@@ -475,7 +548,7 @@ function(cpm_add_patches)
475
548
476
549
# Find the patch program.
477
550
find_program (PATCH_EXECUTABLE patch )
478
- if (WIN32 AND NOT PATCH_EXECUTABLE )
551
+ if (CMAKE_HOST_WIN32 AND NOT PATCH_EXECUTABLE )
479
552
# The Windows git executable is distributed with patch.exe. Find the path to the executable, if
480
553
# it exists, then search `../usr/bin` and `../../usr/bin` for patch.exe.
481
554
find_package (Git QUIET )
@@ -575,14 +648,6 @@ endfunction()
575
648
function (CPMAddPackage )
576
649
cpm_set_policies ()
577
650
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
-
586
651
set (oneValueArgs
587
652
NAME
588
653
FORCE
@@ -605,10 +670,26 @@ function(CPMAddPackage)
605
670
606
671
set (multiValueArgs URL OPTIONS DOWNLOAD_COMMAND PATCHES )
607
672
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
+
608
690
cmake_parse_arguments (CPM_ARGS "" "${oneValueArgs} " "${multiValueArgs} " "${ARGN} " )
609
691
610
692
# Set default values for arguments
611
-
612
693
if (NOT DEFINED CPM_ARGS_VERSION )
613
694
if (DEFINED CPM_ARGS_GIT_TAG )
614
695
cpm_get_version_from_git_tag ("${CPM_ARGS_GIT_TAG} " CPM_ARGS_VERSION )
@@ -779,9 +860,19 @@ function(CPMAddPackage)
779
860
set (download_directory ${CPM_SOURCE_CACHE} /${lower_case_name}/${CPM_ARGS_CUSTOM_CACHE_KEY} )
780
861
elseif (CPM_USE_NAMED_CACHE_DIRECTORIES )
781
862
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
+ )
782
868
set (download_directory ${CPM_SOURCE_CACHE} /${lower_case_name}/${origin_hash}/${CPM_ARGS_NAME} )
783
869
else ()
784
870
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
+ )
785
876
set (download_directory ${CPM_SOURCE_CACHE} /${lower_case_name}/${origin_hash} )
786
877
endif ()
787
878
# Expand `download_directory` relative path. This is important because EXISTS doesn't work for
@@ -848,7 +939,9 @@ function(CPMAddPackage)
848
939
endif ()
849
940
endif ()
850
941
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 ()
852
945
853
946
if (CPM_PACKAGE_LOCK_ENABLED )
854
947
if ((CPM_ARGS_VERSION AND NOT CPM_ARGS_SOURCE_DIR ) OR CPM_INCLUDE_ALL_IN_PACKAGE_LOCK )
@@ -869,8 +962,9 @@ function(CPMAddPackage)
869
962
# Calling FetchContent_MakeAvailable will then internally forward these options to
870
963
# add_subdirectory. Up until these changes, we had to call FetchContent_Populate and
871
964
# 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.
872
966
set (fetchContentDeclareExtraArgs "" )
873
- if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28.0 " )
967
+ if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.30.3 " )
874
968
if (${CPM_ARGS_EXCLUDE_FROM_ALL} )
875
969
list (APPEND fetchContentDeclareExtraArgs EXCLUDE_FROM_ALL )
876
970
endif ()
@@ -896,7 +990,7 @@ function(CPMAddPackage)
896
990
if (CPM_SOURCE_CACHE AND download_directory )
897
991
file (LOCK ${download_directory} /../cmake.lock RELEASE )
898
992
endif ()
899
- if (${populated} AND ${CMAKE_VERSION} VERSION_LESS "3.28.0 " )
993
+ if (${populated} AND ${CMAKE_VERSION} VERSION_LESS "3.30.3 " )
900
994
cpm_add_subdirectory (
901
995
"${CPM_ARGS_NAME} "
902
996
"${DOWNLOAD_ONLY} "
@@ -1098,7 +1192,7 @@ function(cpm_fetch_package PACKAGE DOWNLOAD_ONLY populated)
1098
1192
string (TOLOWER "${PACKAGE} " lower_case_name )
1099
1193
1100
1194
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 " )
1102
1196
if (DOWNLOAD_ONLY )
1103
1197
# MakeAvailable will call add_subdirectory internally which is not what we want when
1104
1198
# DOWNLOAD_ONLY is set. Populate will only download the dependency without adding it to the
0 commit comments