From 1b60519efea58c668c61ff42171ee7babca8e46f Mon Sep 17 00:00:00 2001 From: Arno Moonen Date: Wed, 24 Aug 2022 14:34:28 +0200 Subject: [PATCH] Add support for conditional dependencies via INCLUDE_IF keyword. See cpm-cmake/CPM.cmake#391 for more details. --- README.md | 1 + cmake/CPM.cmake | 76 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2fd49a64..1b213cdb 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ CPMAddPackage( VERSION # The minimum version of the dependency (optional, defaults to 0) OPTIONS # Configuration options passed to the dependency (optional) DOWNLOAD_ONLY # If set, the project is downloaded, but not configured (optional) + INCLUDE_IF # If set, the value has to evaluate to true for the dependency to be added (optional) [...] # Origin parameters forwarded to FetchContent_Declare, see below ) ``` diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake index 7aa8b665..d845fcdf 100644 --- a/cmake/CPM.cmake +++ b/cmake/CPM.cmake @@ -262,7 +262,7 @@ endfunction() # Find a package locally or fallback to CPMAddPackage function(CPMFindPackage) - set(oneValueArgs NAME VERSION GIT_TAG FIND_PACKAGE_ARGUMENTS) + set(oneValueArgs NAME VERSION GIT_TAG FIND_PACKAGE_ARGUMENTS INCLUDE_IF) cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "" ${ARGN}) @@ -272,6 +272,33 @@ function(CPMFindPackage) endif() endif() + if(DEFINED CPM_ARGS_INCLUDE_IF) + + # Filter out INCLUDE_IF from arguments + cpm_remove_one_value_arg(INCLUDE_IF ARGN ${ARGN}) + + # If INCLUDE_IF evaluates to false, do not add the package, but do add it to the package lock + # and register it. + if(NOT CPM_ARGS_INCLUDE_IF) + CPMRegisterPackage("${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}") + if(CPM_PACKAGE_LOCK_ENABLED) + if((CPM_ARGS_VERSION AND NOT CPM_ARGS_SOURCE_DIR) OR CPM_INCLUDE_ALL_IN_PACKAGE_LOCK) + cpm_add_to_package_lock(${CPM_ARGS_NAME} "${ARGN}") + elseif(CPM_ARGS_SOURCE_DIR) + cpm_add_comment_to_package_lock(${CPM_ARGS_NAME} "local directory") + else() + cpm_add_comment_to_package_lock(${CPM_ARGS_NAME} "${ARGN}") + endif() + endif() + + message( + STATUS + "${CPM_INDENT} skipping package ${CPM_ARGS_NAME}@${CPM_ARGS_VERSION} (INCLUDE_IF: ${CPM_ARGS_INCLUDE_IF})" + ) + return() + endif() + endif() + set(downloadPackage ${CPM_DOWNLOAD_ALL}) if(DEFINED CPM_DOWNLOAD_${CPM_ARGS_NAME}) set(downloadPackage ${CPM_DOWNLOAD_${CPM_ARGS_NAME}}) @@ -495,6 +522,25 @@ function(cpm_override_fetchcontent contentName) set_property(GLOBAL PROPERTY ${propertyName} TRUE) endfunction() +# filter out a one value keyword and its value from a list of arguments +function(cpm_remove_one_value_arg KEYWORD OUTPUT_VAR) + # Always start with a copy of the data + set(RESULT ${ARGN}) + + # Find the keyword location + list(FIND RESULT ${KEYWORD} KEYWORD_INDEX) + if(KEYWORD_INDEX GREATER_EQUAL 0) + # Keyword found; remove data at the same index twice to get rid of the keyword and its value + list(REMOVE_AT RESULT ${KEYWORD_INDEX}) + list(REMOVE_AT RESULT ${KEYWORD_INDEX}) + endif() + + set(${OUTPUT_VAR} + ${RESULT} + PARENT_SCOPE + ) +endfunction() + # Download and add a package from source function(CPMAddPackage) cpm_set_policies() @@ -524,6 +570,7 @@ function(CPMAddPackage) GIT_SHALLOW EXCLUDE_FROM_ALL SOURCE_SUBDIR + INCLUDE_IF ) set(multiValueArgs URL OPTIONS) @@ -538,6 +585,33 @@ function(CPMAddPackage) endif() endif() + if(DEFINED CPM_ARGS_INCLUDE_IF) + + # Filter out INCLUDE_IF from arguments + cpm_remove_one_value_arg(INCLUDE_IF ARGN ${ARGN}) + + # If INCLUDE_IF evaluates to false, do not add the package, but do add it to the package lock + # and register it. + if(NOT CPM_ARGS_INCLUDE_IF) + CPMRegisterPackage("${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}") + if(CPM_PACKAGE_LOCK_ENABLED) + if((CPM_ARGS_VERSION AND NOT CPM_ARGS_SOURCE_DIR) OR CPM_INCLUDE_ALL_IN_PACKAGE_LOCK) + cpm_add_to_package_lock(${CPM_ARGS_NAME} "${ARGN}") + elseif(CPM_ARGS_SOURCE_DIR) + cpm_add_comment_to_package_lock(${CPM_ARGS_NAME} "local directory") + else() + cpm_add_comment_to_package_lock(${CPM_ARGS_NAME} "${ARGN}") + endif() + endif() + + message( + STATUS + "${CPM_INDENT} skipping package ${CPM_ARGS_NAME}@${CPM_ARGS_VERSION} (INCLUDE_IF: ${CPM_ARGS_INCLUDE_IF})" + ) + return() + endif() + endif() + if(CPM_ARGS_DOWNLOAD_ONLY) set(DOWNLOAD_ONLY ${CPM_ARGS_DOWNLOAD_ONLY}) else()