mirror of
https://github.com/cpm-cmake/CPM.cmake.git
synced 2025-11-18 07:07:47 -05:00
Scope package options to avoid changing the local scope (#235)
* Fix #222 * Fix #222 * move policy change and local options to cpm_add_subdirectory * change default policy as well see https://gitlab.kitware.com/cmake/cmake/-/issues/20312 * add test * update check to not use the NOT operator (interestingly it works as expected locally) * simplify test by not using options * check options in tests Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com>
This commit is contained in:
@@ -132,7 +132,6 @@ if(NOT CPM_DONT_CREATE_PACKAGE_LOCK)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
include(CMakeParseArguments)
|
|
||||||
|
|
||||||
# Try to infer package name from git repository uri (path or url)
|
# Try to infer package name from git repository uri (path or url)
|
||||||
function(cpm_package_name_from_git_uri URI RESULT)
|
function(cpm_package_name_from_git_uri URI RESULT)
|
||||||
@@ -516,16 +515,6 @@ function(CPMAddPackage)
|
|||||||
|
|
||||||
CPMRegisterPackage("${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}")
|
CPMRegisterPackage("${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}")
|
||||||
|
|
||||||
if(CPM_ARGS_OPTIONS)
|
|
||||||
foreach(OPTION ${CPM_ARGS_OPTIONS})
|
|
||||||
cpm_parse_option(${OPTION})
|
|
||||||
set(${OPTION_KEY}
|
|
||||||
${OPTION_VALUE}
|
|
||||||
CACHE INTERNAL ""
|
|
||||||
)
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(DEFINED CPM_ARGS_GIT_TAG)
|
if(DEFINED CPM_ARGS_GIT_TAG)
|
||||||
set(PACKAGE_INFO "${CPM_ARGS_GIT_TAG}")
|
set(PACKAGE_INFO "${CPM_ARGS_GIT_TAG}")
|
||||||
elseif(DEFINED CPM_ARGS_SOURCE_DIR)
|
elseif(DEFINED CPM_ARGS_SOURCE_DIR)
|
||||||
@@ -553,7 +542,7 @@ function(CPMAddPackage)
|
|||||||
cpm_add_subdirectory(
|
cpm_add_subdirectory(
|
||||||
"${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}"
|
"${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}"
|
||||||
"${${CPM_ARGS_NAME}_SOURCE_DIR}/${CPM_ARGS_SOURCE_SUBDIR}" "${${CPM_ARGS_NAME}_BINARY_DIR}"
|
"${${CPM_ARGS_NAME}_SOURCE_DIR}/${CPM_ARGS_SOURCE_SUBDIR}" "${${CPM_ARGS_NAME}_BINARY_DIR}"
|
||||||
"${CPM_ARGS_EXCLUDE_FROM_ALL}"
|
"${CPM_ARGS_EXCLUDE_FROM_ALL}" "${CPM_ARGS_OPTIONS}"
|
||||||
)
|
)
|
||||||
set(CPM_SKIP_FETCH TRUE)
|
set(CPM_SKIP_FETCH TRUE)
|
||||||
set(PACKAGE_INFO "${PACKAGE_INFO} at ${download_directory}")
|
set(PACKAGE_INFO "${PACKAGE_INFO} at ${download_directory}")
|
||||||
@@ -597,7 +586,7 @@ function(CPMAddPackage)
|
|||||||
cpm_add_subdirectory(
|
cpm_add_subdirectory(
|
||||||
"${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}"
|
"${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}"
|
||||||
"${${CPM_ARGS_NAME}_SOURCE_DIR}/${CPM_ARGS_SOURCE_SUBDIR}" "${${CPM_ARGS_NAME}_BINARY_DIR}"
|
"${${CPM_ARGS_NAME}_SOURCE_DIR}/${CPM_ARGS_SOURCE_SUBDIR}" "${${CPM_ARGS_NAME}_BINARY_DIR}"
|
||||||
"${CPM_ARGS_EXCLUDE_FROM_ALL}"
|
"${CPM_ARGS_EXCLUDE_FROM_ALL}" "${CPM_ARGS_OPTIONS}"
|
||||||
)
|
)
|
||||||
cpm_get_fetch_properties("${CPM_ARGS_NAME}")
|
cpm_get_fetch_properties("${CPM_ARGS_NAME}")
|
||||||
endif()
|
endif()
|
||||||
@@ -722,13 +711,31 @@ function(cpm_get_fetch_properties PACKAGE)
|
|||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# adds a package as a subdirectory if viable, according to provided options
|
# adds a package as a subdirectory if viable, according to provided options
|
||||||
function(cpm_add_subdirectory PACKAGE DOWNLOAD_ONLY SOURCE_DIR BINARY_DIR EXCLUDE)
|
function(
|
||||||
|
cpm_add_subdirectory
|
||||||
|
PACKAGE
|
||||||
|
DOWNLOAD_ONLY
|
||||||
|
SOURCE_DIR
|
||||||
|
BINARY_DIR
|
||||||
|
EXCLUDE
|
||||||
|
OPTIONS
|
||||||
|
)
|
||||||
if(NOT DOWNLOAD_ONLY AND EXISTS ${SOURCE_DIR}/CMakeLists.txt)
|
if(NOT DOWNLOAD_ONLY AND EXISTS ${SOURCE_DIR}/CMakeLists.txt)
|
||||||
if(EXCLUDE)
|
if(EXCLUDE)
|
||||||
set(addSubdirectoryExtraArgs EXCLUDE_FROM_ALL)
|
set(addSubdirectoryExtraArgs EXCLUDE_FROM_ALL)
|
||||||
else()
|
else()
|
||||||
set(addSubdirectoryExtraArgs "")
|
set(addSubdirectoryExtraArgs "")
|
||||||
endif()
|
endif()
|
||||||
|
if(OPTIONS)
|
||||||
|
# the policy allows us to change options without caching
|
||||||
|
cmake_policy(SET CMP0077 NEW)
|
||||||
|
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
||||||
|
|
||||||
|
foreach(OPTION ${OPTIONS})
|
||||||
|
cpm_parse_option(${OPTION})
|
||||||
|
set(${OPTION_KEY} ${OPTION_VALUE})
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
set(CPM_OLD_INDENT "${CPM_INDENT}")
|
set(CPM_OLD_INDENT "${CPM_INDENT}")
|
||||||
set(CPM_INDENT "${CPM_INDENT} ${PACKAGE}:")
|
set(CPM_INDENT "${CPM_INDENT} ${PACKAGE}:")
|
||||||
add_subdirectory(${SOURCE_DIR} ${BINARY_DIR} ${addSubdirectoryExtraArgs})
|
add_subdirectory(${SOURCE_DIR} ${BINARY_DIR} ${addSubdirectoryExtraArgs})
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ endfunction()
|
|||||||
|
|
||||||
function(ASSERT_NOT_DEFINED KEY)
|
function(ASSERT_NOT_DEFINED KEY)
|
||||||
if(DEFINED ${KEY})
|
if(DEFINED ${KEY})
|
||||||
message(FATAL_ERROR "assertion failed: '${KEY}' is defiend")
|
message(FATAL_ERROR "assertion failed: '${KEY}' is defiend (${${KEY}})")
|
||||||
else()
|
else()
|
||||||
message(STATUS "test passed: '${KEY}' is not defined")
|
message(STATUS "test passed: '${KEY}' is not defined")
|
||||||
endif()
|
endif()
|
||||||
@@ -48,7 +48,15 @@ function(ASSERT_TRUTHY KEY)
|
|||||||
if(${${KEY}})
|
if(${${KEY}})
|
||||||
message(STATUS "test passed: '${KEY}' is set truthy")
|
message(STATUS "test passed: '${KEY}' is set truthy")
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "assertion failed: value of '${KEY}' is not true (${${KEY}})")
|
message(FATAL_ERROR "assertion failed: value of '${KEY}' is not truthy (${${KEY}})")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(ASSERT_FALSY KEY)
|
||||||
|
if(${${KEY}})
|
||||||
|
message(FATAL_ERROR "assertion failed: value of '${KEY}' is not falsy (${${KEY}})")
|
||||||
|
else()
|
||||||
|
message(STATUS "test passed: '${KEY}' is set falsy")
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
|||||||
33
test/unit/local_dependency/OptionsCMakeLists.txt.in
Normal file
33
test/unit/local_dependency/OptionsCMakeLists.txt.in
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
|
||||||
|
|
||||||
|
project(CPMTest)
|
||||||
|
|
||||||
|
# ---- Options ----
|
||||||
|
|
||||||
|
option(ENABLE_TEST_COVERAGE "Enable test coverage" OFF)
|
||||||
|
|
||||||
|
# ---- Dependencies ----
|
||||||
|
|
||||||
|
include(@CPM_PATH@/CPM.cmake)
|
||||||
|
|
||||||
|
CPMAddPackage(
|
||||||
|
NAME Dependency
|
||||||
|
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/dependency
|
||||||
|
OPTIONS "DEFINE_ALTERNATIVE_FUNCTION YES"
|
||||||
|
EXCLUDE_FROM_ALL YES
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- Dependencies ----
|
||||||
|
|
||||||
|
alternative_dependency_function()
|
||||||
|
|
||||||
|
# ---- Check parameters ----
|
||||||
|
|
||||||
|
include(@CPM_PATH@/testing.cmake)
|
||||||
|
|
||||||
|
message("DEFINE_ALTERNATIVE_FUNCTION: ${DEFINE_ALTERNATIVE_FUNCTION}")
|
||||||
|
|
||||||
|
# this option is overridden by CPM.cmake
|
||||||
|
ASSERT_NOT_DEFINED(DEFINE_ALTERNATIVE_FUNCTION)
|
||||||
|
# this option is leaked by the dependency
|
||||||
|
ASSERT_EQUAL(${LEAKED_OPTION} "OFF")
|
||||||
@@ -1,3 +1,14 @@
|
|||||||
function(dependency_function)
|
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
|
||||||
message("called external method")
|
|
||||||
endfunction()
|
option(DEFINE_ALTERNATIVE_FUNCTION "define the alternative function" OFF)
|
||||||
|
option(LEAKED_OPTION "this option will be leaked to the outer scope" OFF)
|
||||||
|
|
||||||
|
if(NOT DEFINE_ALTERNATIVE_FUNCTION)
|
||||||
|
function(dependency_function)
|
||||||
|
message("called external method")
|
||||||
|
endfunction()
|
||||||
|
else()
|
||||||
|
function(alternative_dependency_function)
|
||||||
|
message("called alternative external method")
|
||||||
|
endfunction()
|
||||||
|
endif()
|
||||||
|
|||||||
19
test/unit/options.cmake
Normal file
19
test/unit/options.cmake
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
include(${CPM_PATH}/testing.cmake)
|
||||||
|
|
||||||
|
set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/source_dir)
|
||||||
|
|
||||||
|
set(TEST_DEPENDENCY_NAME Dependency)
|
||||||
|
|
||||||
|
configure_package_config_file(
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/local_dependency/OptionsCMakeLists.txt.in"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/local_dependency/CMakeLists.txt"
|
||||||
|
INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/junk
|
||||||
|
)
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${CMAKE_COMMAND} "-H${CMAKE_CURRENT_LIST_DIR}/local_dependency" "-B${TEST_BUILD_DIR}"
|
||||||
|
RESULT_VARIABLE ret
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_equal(${ret} "0")
|
||||||
Reference in New Issue
Block a user