Skip to content

Commit 7cc4741

Browse files
authored
Merge pull request #17 from ufz/bilke-cpm-update
Update CPM.cmake to 0.40.1
2 parents 755319a + 1171143 commit 7cc4741

File tree

2 files changed

+118
-11
lines changed

2 files changed

+118
-11
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ CPMFindPackage(
1717
GIT_TAG 098dd0fe07a31618f3c2a9f8727bb01c8c5d61e2
1818
DOWNLOAD_ONLY YES
1919
)
20-
if(tclap_ADDED)
20+
if(tclap_ADDED AND NOT TARGET tclap)
2121
add_library(tclap INTERFACE IMPORTED)
2222
target_include_directories(
2323
tclap SYSTEM INTERFACE ${tclap_SOURCE_DIR}/include

cmake/CPM.cmake

+117-10
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ if(NOT COMMAND cpm_message)
4242
endfunction()
4343
endif()
4444

45-
set(CURRENT_CPM_VERSION 0.39.0)
45+
set(CURRENT_CPM_VERSION 0.40.1)
4646

4747
get_filename_component(CPM_CURRENT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" REALPATH)
4848
if(CPM_DIRECTORY)
@@ -391,8 +391,8 @@ function(cpm_parse_add_package_single_arg arg outArgs)
391391
# We don't try to parse the version if it's not provided explicitly. cpm_get_version_from_url
392392
# should do this at a later point
393393
else()
394-
# We should never get here. This is an assertion and hitting it means there's a bug in the code
395-
# above. A packageType was set, but not handled by this if-else.
394+
# We should never get here. This is an assertion and hitting it means there's a problem with the
395+
# code above. A packageType was set, but not handled by this if-else.
396396
message(FATAL_ERROR "${CPM_INDENT} Unsupported package type '${packageType}' of '${arg}'")
397397
endif()
398398

@@ -464,6 +464,69 @@ function(cpm_check_git_working_dir_is_clean repoPath gitTag isClean)
464464

465465
endfunction()
466466

467+
# Add PATCH_COMMAND to CPM_ARGS_UNPARSED_ARGUMENTS. This method consumes a list of files in ARGN
468+
# then generates a `PATCH_COMMAND` appropriate for `ExternalProject_Add()`. This command is appended
469+
# to the parent scope's `CPM_ARGS_UNPARSED_ARGUMENTS`.
470+
function(cpm_add_patches)
471+
# Return if no patch files are supplied.
472+
if(NOT ARGN)
473+
return()
474+
endif()
475+
476+
# Find the patch program.
477+
find_program(PATCH_EXECUTABLE patch)
478+
if(WIN32 AND NOT PATCH_EXECUTABLE)
479+
# The Windows git executable is distributed with patch.exe. Find the path to the executable, if
480+
# it exists, then search `../../usr/bin` for patch.exe.
481+
find_package(Git QUIET)
482+
if(GIT_EXECUTABLE)
483+
get_filename_component(extra_search_path ${GIT_EXECUTABLE} DIRECTORY)
484+
get_filename_component(extra_search_path ${extra_search_path} DIRECTORY)
485+
get_filename_component(extra_search_path ${extra_search_path} DIRECTORY)
486+
find_program(PATCH_EXECUTABLE patch HINTS "${extra_search_path}/usr/bin")
487+
endif()
488+
endif()
489+
if(NOT PATCH_EXECUTABLE)
490+
message(FATAL_ERROR "Couldn't find `patch` executable to use with PATCHES keyword.")
491+
endif()
492+
493+
# Create a temporary
494+
set(temp_list ${CPM_ARGS_UNPARSED_ARGUMENTS})
495+
496+
# Ensure each file exists (or error out) and add it to the list.
497+
set(first_item True)
498+
foreach(PATCH_FILE ${ARGN})
499+
# Make sure the patch file exists, if we can't find it, try again in the current directory.
500+
if(NOT EXISTS "${PATCH_FILE}")
501+
if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/${PATCH_FILE}")
502+
message(FATAL_ERROR "Couldn't find patch file: '${PATCH_FILE}'")
503+
endif()
504+
set(PATCH_FILE "${CMAKE_CURRENT_LIST_DIR}/${PATCH_FILE}")
505+
endif()
506+
507+
# Convert to absolute path for use with patch file command.
508+
get_filename_component(PATCH_FILE "${PATCH_FILE}" ABSOLUTE)
509+
510+
# The first patch entry must be preceded by "PATCH_COMMAND" while the following items are
511+
# preceded by "&&".
512+
if(first_item)
513+
set(first_item False)
514+
list(APPEND temp_list "PATCH_COMMAND")
515+
else()
516+
list(APPEND temp_list "&&")
517+
endif()
518+
# Add the patch command to the list
519+
list(APPEND temp_list "${PATCH_EXECUTABLE}" "-p1" "<" "${PATCH_FILE}")
520+
endforeach()
521+
522+
# Move temp out into parent scope.
523+
set(CPM_ARGS_UNPARSED_ARGUMENTS
524+
${temp_list}
525+
PARENT_SCOPE
526+
)
527+
528+
endfunction()
529+
467530
# method to overwrite internal FetchContent properties, to allow using CPM.cmake to overload
468531
# FetchContent calls. As these are internal cmake properties, this method should be used carefully
469532
# and may need modification in future CMake versions. Source:
@@ -537,7 +600,7 @@ function(CPMAddPackage)
537600
CUSTOM_CACHE_KEY
538601
)
539602

540-
set(multiValueArgs URL OPTIONS DOWNLOAD_COMMAND)
603+
set(multiValueArgs URL OPTIONS DOWNLOAD_COMMAND PATCHES)
541604

542605
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}")
543606

@@ -628,6 +691,7 @@ function(CPMAddPackage)
628691
SOURCE_DIR "${PACKAGE_SOURCE}"
629692
EXCLUDE_FROM_ALL "${CPM_ARGS_EXCLUDE_FROM_ALL}"
630693
SYSTEM "${CPM_ARGS_SYSTEM}"
694+
PATCHES "${CPM_ARGS_PATCHES}"
631695
OPTIONS "${CPM_ARGS_OPTIONS}"
632696
SOURCE_SUBDIR "${CPM_ARGS_SOURCE_SUBDIR}"
633697
DOWNLOAD_ONLY "${DOWNLOAD_ONLY}"
@@ -683,6 +747,8 @@ function(CPMAddPackage)
683747
set(CPM_FETCHCONTENT_BASE_DIR ${CMAKE_BINARY_DIR}/_deps)
684748
endif()
685749

750+
cpm_add_patches(${CPM_ARGS_PATCHES})
751+
686752
if(DEFINED CPM_ARGS_DOWNLOAD_COMMAND)
687753
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS DOWNLOAD_COMMAND ${CPM_ARGS_DOWNLOAD_COMMAND})
688754
elseif(DEFINED CPM_ARGS_SOURCE_DIR)
@@ -796,14 +862,38 @@ function(CPMAddPackage)
796862
)
797863

798864
if(NOT CPM_SKIP_FETCH)
865+
# CMake 3.28 added EXCLUDE, SYSTEM (3.25), and SOURCE_SUBDIR (3.18) to FetchContent_Declare.
866+
# Calling FetchContent_MakeAvailable will then internally forward these options to
867+
# add_subdirectory. Up until these changes, we had to call FetchContent_Populate and
868+
# add_subdirectory separately, which is no longer necessary and has been deprecated as of 3.30.
869+
set(fetchContentDeclareExtraArgs "")
870+
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28.0")
871+
if(${CPM_ARGS_EXCLUDE_FROM_ALL})
872+
list(APPEND fetchContentDeclareExtraArgs EXCLUDE_FROM_ALL)
873+
endif()
874+
if(${CPM_ARGS_SYSTEM})
875+
list(APPEND fetchContentDeclareExtraArgs SYSTEM)
876+
endif()
877+
if(DEFINED CPM_ARGS_SOURCE_SUBDIR)
878+
list(APPEND fetchContentDeclareExtraArgs SOURCE_SUBDIR ${CPM_ARGS_SOURCE_SUBDIR})
879+
endif()
880+
# For CMake version <3.28 OPTIONS are parsed in cpm_add_subdirectory
881+
if(CPM_ARGS_OPTIONS AND NOT DOWNLOAD_ONLY)
882+
foreach(OPTION ${CPM_ARGS_OPTIONS})
883+
cpm_parse_option("${OPTION}")
884+
set(${OPTION_KEY} "${OPTION_VALUE}")
885+
endforeach()
886+
endif()
887+
endif()
799888
cpm_declare_fetch(
800-
"${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}" "${PACKAGE_INFO}" "${CPM_ARGS_UNPARSED_ARGUMENTS}"
889+
"${CPM_ARGS_NAME}" ${fetchContentDeclareExtraArgs} "${CPM_ARGS_UNPARSED_ARGUMENTS}"
801890
)
802-
cpm_fetch_package("${CPM_ARGS_NAME}" populated)
891+
892+
cpm_fetch_package("${CPM_ARGS_NAME}" ${DOWNLOAD_ONLY} populated ${CPM_ARGS_UNPARSED_ARGUMENTS})
803893
if(CPM_SOURCE_CACHE AND download_directory)
804894
file(LOCK ${download_directory}/../cmake.lock RELEASE)
805895
endif()
806-
if(${populated})
896+
if(${populated} AND ${CMAKE_VERSION} VERSION_LESS "3.28.0")
807897
cpm_add_subdirectory(
808898
"${CPM_ARGS_NAME}"
809899
"${DOWNLOAD_ONLY}"
@@ -914,7 +1004,7 @@ function(CPMGetPackageVersion PACKAGE OUTPUT)
9141004
endfunction()
9151005

9161006
# declares a package in FetchContent_Declare
917-
function(cpm_declare_fetch PACKAGE VERSION INFO)
1007+
function(cpm_declare_fetch PACKAGE)
9181008
if(${CPM_DRY_RUN})
9191009
cpm_message(STATUS "${CPM_INDENT} Package not declared (dry run)")
9201010
return()
@@ -990,7 +1080,7 @@ endfunction()
9901080

9911081
# downloads a previously declared package via FetchContent and exports the variables
9921082
# `${PACKAGE}_SOURCE_DIR` and `${PACKAGE}_BINARY_DIR` to the parent scope
993-
function(cpm_fetch_package PACKAGE populated)
1083+
function(cpm_fetch_package PACKAGE DOWNLOAD_ONLY populated)
9941084
set(${populated}
9951085
FALSE
9961086
PARENT_SCOPE
@@ -1005,7 +1095,24 @@ function(cpm_fetch_package PACKAGE populated)
10051095
string(TOLOWER "${PACKAGE}" lower_case_name)
10061096

10071097
if(NOT ${lower_case_name}_POPULATED)
1008-
FetchContent_Populate(${PACKAGE})
1098+
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28.0")
1099+
if(DOWNLOAD_ONLY)
1100+
# MakeAvailable will call add_subdirectory internally which is not what we want when
1101+
# DOWNLOAD_ONLY is set. Populate will only download the dependency without adding it to the
1102+
# build
1103+
FetchContent_Populate(
1104+
${PACKAGE}
1105+
SOURCE_DIR "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-src"
1106+
BINARY_DIR "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-build"
1107+
SUBBUILD_DIR "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-subbuild"
1108+
${ARGN}
1109+
)
1110+
else()
1111+
FetchContent_MakeAvailable(${PACKAGE})
1112+
endif()
1113+
else()
1114+
FetchContent_Populate(${PACKAGE})
1115+
endif()
10091116
set(${populated}
10101117
TRUE
10111118
PARENT_SCOPE

0 commit comments

Comments
 (0)