diff --git a/README.md b/README.md index dbce986..5a792d3 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,12 @@ CPM can be configured to use `find_package` to search for locally installed depe If the option `CPM_LOCAL_PACKAGES_ONLY` is set, CPM will emit an error if the dependency is not found locally. These options can also be set as environmental variables. +## Local package override + +Library developers are often in the situation where they work on a locally checked out dependency at the same time as on a consumer. +It is possible to override the consumer's dependency version with the local one by supplying the CMake option `CPM__SOURCE`. +For example, to use the local version of `Dep` at the absolute path `/path/to/dep`, the consumer can be build with `cmake -H. -Bbuild -DCPM_Dep_SOURCE=/path/to/dep`. + ## Snippets These examples demonstrate how to include some well-known projects with CPM. diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake index 663c5c8..43c7d4e 100644 --- a/cmake/CPM.cmake +++ b/cmake/CPM.cmake @@ -28,7 +28,7 @@ cmake_minimum_required(VERSION 3.14 FATAL_ERROR) -set(CURRENT_CPM_VERSION 0.25.1) +set(CURRENT_CPM_VERSION 0.26) if(CPM_DIRECTORY) if(NOT CPM_DIRECTORY STREQUAL CMAKE_CURRENT_LIST_DIR) @@ -243,12 +243,23 @@ function(CPMAddPackage) return() endif() + # Check for manual overrides + if (NOT "${CPM_${CPM_ARGS_NAME}_SOURCE}" STREQUAL "") + set(PACKAGE_SOURCE ${CPM_${CPM_ARGS_NAME}_SOURCE}) + set(CPM_${CPM_ARGS_NAME}_SOURCE "") + CPMAddPackage( + NAME ${CPM_ARGS_NAME} + SOURCE_DIR ${PACKAGE_SOURCE} + ) + cpm_export_variables(${CPM_ARGS_NAME}) + return() + endif() + # Check for available declaration - if (DEFINED "CPM_DECLARATION_${CPM_ARGS_NAME}" AND NOT "${CPM_DECLARATION_${CPM_ARGS_NAME}}" STREQUAL "") + if (NOT "${CPM_DECLARATION_${CPM_ARGS_NAME}}" STREQUAL "") set(declaration ${CPM_DECLARATION_${CPM_ARGS_NAME}}) set(CPM_DECLARATION_${CPM_ARGS_NAME} "") CPMAddPackage(${declaration}) - set(CPM_DECLARATION_${CPM_ARGS_NAME} "${declaration}") cpm_export_variables(${CPM_ARGS_NAME}) # checking again to ensure version and option compatibility CPMCheckIfPackageAlreadyAdded(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" "${CPM_ARGS_OPTIONS}") @@ -279,6 +290,8 @@ function(CPMAddPackage) if (DEFINED CPM_ARGS_GIT_TAG) set(PACKAGE_INFO "${CPM_ARGS_GIT_TAG}") + elseif(DEFINED CPM_ARGS_SOURCE_DIR) + set(PACKAGE_INFO "${CPM_ARGS_SOURCE_DIR}") else() set(PACKAGE_INFO "${CPM_ARGS_VERSION}") endif() diff --git a/test/unit/package-lock.cmake b/test/unit/package-lock.cmake index e26003d..f7d4abc 100644 --- a/test/unit/package-lock.cmake +++ b/test/unit/package-lock.cmake @@ -45,4 +45,5 @@ ASSERT_NOT_EXISTS(${CMAKE_CURRENT_LIST_DIR}/test_project/package-lock.cmake) updatePackageLock() ASSERT_EXISTS(${CMAKE_CURRENT_LIST_DIR}/test_project/package-lock.cmake) configureWithDeclare(NO) +execute_process(COMMAND ${CMAKE_COMMAND} -E rm -f ${CMAKE_CURRENT_LIST_DIR}/test_project/package-lock.cmake) diff --git a/test/unit/package-override.cmake b/test/unit/package-override.cmake new file mode 100644 index 0000000..3ab7b6d --- /dev/null +++ b/test/unit/package-override.cmake @@ -0,0 +1,20 @@ + +include(CMakePackageConfigHelpers) +include(${CPM_PATH}/testing.cmake) + +set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/project-override) + +execute_process(COMMAND ${CMAKE_COMMAND} -E rm -rf ${TEST_BUILD_DIR}) + +configure_package_config_file( + "${CMAKE_CURRENT_LIST_DIR}/test_project/OverrideCMakeLists.txt.in" + "${CMAKE_CURRENT_LIST_DIR}/test_project/CMakeLists.txt" + INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/junk +) + +execute_process( + COMMAND ${CMAKE_COMMAND} -H${CMAKE_CURRENT_LIST_DIR}/test_project -B${TEST_BUILD_DIR} -DCPM_Dependency_SOURCE=${CMAKE_CURRENT_LIST_DIR}/test_project/dependency + RESULT_VARIABLE ret +) + +ASSERT_EQUAL(${ret} "0") diff --git a/test/unit/test_project/OverrideCMakeLists.txt.in b/test/unit/test_project/OverrideCMakeLists.txt.in new file mode 100644 index 0000000..26e1ebc --- /dev/null +++ b/test/unit/test_project/OverrideCMakeLists.txt.in @@ -0,0 +1,19 @@ +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 +) + +# ---- Call dependency method to validate correct addition of directory ---- + +dependency_function()