From ca33abc23670bf52ee7d5706d17fad37994fd359 Mon Sep 17 00:00:00 2001 From: Lars Melchior Date: Wed, 29 Apr 2020 09:18:54 +0200 Subject: [PATCH] create FindXXX.cmake modules for added CPM packages (#112) * create FindXXX.cmake modules for added CPM packages * don't use list(PREPEND) as it unsupported on older CMake versions * use CMAKE_BINARY_DIR * ensure CPM.cmake is initialized only once * import CPM.cmake in modules --- cmake/CPM.cmake | 32 +++++++++++++++++-- cmake/testing.cmake | 12 +++++++ test/unit/modules.cmake | 30 +++++++++++++++++ test/unit/source_dir.cmake | 8 +++-- .../{source_dir => test_project}/.gitignore | 0 .../CMakeLists.txt.in | 8 ++++- .../dependency/CMakeLists.txt | 0 7 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 test/unit/modules.cmake rename test/unit/{source_dir => test_project}/.gitignore (100%) rename test/unit/{source_dir => test_project}/CMakeLists.txt.in (67%) rename test/unit/{source_dir => test_project}/dependency/CMakeLists.txt (100%) diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake index 9975af8..1b859ce 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.20) +set(CURRENT_CPM_VERSION 0.21) if(CPM_DIRECTORY) if(NOT ${CPM_DIRECTORY} MATCHES ${CMAKE_CURRENT_LIST_DIR}) @@ -41,14 +41,23 @@ See https://github.com/TheLartians/CPM.cmake for more information." endif() return() endif() + + get_property(CPM_INITIALIZED GLOBAL "" PROPERTY CPM_INITIALIZED SET) + if (CPM_INITIALIZED) + return() + endif() endif() +set_property(GLOBAL PROPERTY CPM_INITIALIZED true) + option(CPM_USE_LOCAL_PACKAGES "Always try to use `find_package` to get dependencies" $ENV{CPM_USE_LOCAL_PACKAGES}) option(CPM_LOCAL_PACKAGES_ONLY "Only use `find_package` to get dependencies" $ENV{CPM_LOCAL_PACKAGES_ONLY}) option(CPM_DOWNLOAD_ALL "Always download dependencies from source" $ENV{CPM_DOWNLOAD_ALL}) +option(CPM_DONT_UPDATE_MODULE_PATH "Don't update the module path to allow using find_package" $ENV{CPM_DONT_UPDATE_MODULE_PATH}) set(CPM_VERSION ${CURRENT_CPM_VERSION} CACHE INTERNAL "") set(CPM_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} CACHE INTERNAL "") +set(CPM_FILE ${CMAKE_CURRENT_LIST_FILE} CACHE INTERNAL "") set(CPM_PACKAGES "" CACHE INTERNAL "") set(CPM_DRY_RUN OFF CACHE INTERNAL "Don't download or configure dependencies (for testing)") @@ -60,6 +69,15 @@ endif() set(CPM_SOURCE_CACHE ${CPM_SOURCE_CACHE_DEFAULT} CACHE PATH "Directory to downlaod CPM dependencies") +if (NOT CPM_DONT_UPDATE_MODULE_PATH) + set(CPM_MODULE_PATH "${CMAKE_BINARY_DIR}/CPM_modules" CACHE INTERNAL "") + # remove old modules + FILE(REMOVE_RECURSE ${CPM_MODULE_PATH}) + file(MAKE_DIRECTORY ${CPM_MODULE_PATH}) + # locally added CPM modules should override global packages + set(CMAKE_MODULE_PATH "${CPM_MODULE_PATH};${CMAKE_MODULE_PATH}") +endif() + include(FetchContent) include(CMakeParseArguments) @@ -80,6 +98,15 @@ function(cpm_find_package NAME VERSION) endif() endfunction() +# Create a custom FindXXX.cmake module for a CPM package +# This prevents `find_package(NAME)` from finding the system library +function(CPMCreateModuleFile Name) + if (NOT CPM_DONT_UPDATE_MODULE_PATH) + # erase any previous modules + FILE(WRITE ${CPM_MODULE_PATH}/Find${Name}.cmake "include(${CPM_FILE})\n${ARGN}\nset(${Name}_FOUND TRUE)") + endif() +endfunction() + # Find a package locally or fallback to CPMAddPackage function(CPMFindPackage) set(oneValueArgs @@ -167,7 +194,7 @@ function(CPMAddPackage) list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS GIT_REPOSITORY "https://gitlab.com/${CPM_ARGS_GITLAB_REPOSITORY}.git") endif() - if (${CPM_ARGS_NAME} IN_LIST CPM_PACKAGES) + if ("${CPM_ARGS_NAME}" IN_LIST CPM_PACKAGES) CPMGetPackageVersion(${CPM_ARGS_NAME} CPM_PACKAGE_VERSION) if(${CPM_PACKAGE_VERSION} VERSION_LESS ${CPM_ARGS_VERSION}) message(WARNING "${CPM_INDENT} requires a newer version of ${CPM_ARGS_NAME} (${CPM_ARGS_VERSION}) than currently included (${CPM_PACKAGE_VERSION}).") @@ -231,6 +258,7 @@ function(CPMAddPackage) cpm_declare_fetch(${CPM_ARGS_NAME} ${CPM_ARGS_VERSION} ${PACKAGE_INFO} "${CPM_ARGS_UNPARSED_ARGUMENTS}" ${FETCH_CONTENT_DECLARE_EXTRA_OPTS}) cpm_fetch_package(${CPM_ARGS_NAME} ${DOWNLOAD_ONLY}) cpm_get_fetch_properties(${CPM_ARGS_NAME}) + CPMCreateModuleFile(${CPM_ARGS_NAME} "CPMAddPackage(${ARGN})") SET(${CPM_ARGS_NAME}_ADDED YES) cpm_export_variables() endfunction() diff --git a/cmake/testing.cmake b/cmake/testing.cmake index 5df6a71..6c9e59e 100644 --- a/cmake/testing.cmake +++ b/cmake/testing.cmake @@ -20,3 +20,15 @@ endfunction() function(ASSERTION_FAILED) message(FATAL_ERROR "assertion failed: ${ARGN}") endfunction() + +function(ASSERT_EXISTS file) + if (NOT EXISTS ${file}) + message(FATAL_ERROR "assertion failed: file ${file} does not exist") + endif() +endfunction() + +function(ASSERT_NOT_EXISTS file) + if (EXISTS ${file}) + message(FATAL_ERROR "assertion failed: file ${file} exists") + endif() +endfunction() diff --git a/test/unit/modules.cmake b/test/unit/modules.cmake new file mode 100644 index 0000000..334b566 --- /dev/null +++ b/test/unit/modules.cmake @@ -0,0 +1,30 @@ + +include(CMakePackageConfigHelpers) +include(${CPM_PATH}/testing.cmake) + +set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/modules) + +function(initProjectWithDependency TEST_DEPENDENCY_NAME) + configure_package_config_file( + "${CMAKE_CURRENT_LIST_DIR}/test_project/CMakeLists.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}" + RESULT_VARIABLE ret + ) + + ASSERT_EQUAL(${ret} "0") +endfunction() + +initProjectWithDependency(A) +ASSERT_EXISTS(${TEST_BUILD_DIR}/CPM_modules) +ASSERT_EXISTS(${TEST_BUILD_DIR}/CPM_modules/FindA.cmake) +ASSERT_NOT_EXISTS(${TEST_BUILD_DIR}/CPM_modules/FindB.cmake) + +initProjectWithDependency(B) +ASSERT_NOT_EXISTS(${TEST_BUILD_DIR}/CPM_modules/FindA.cmake) +ASSERT_EXISTS(${TEST_BUILD_DIR}/CPM_modules/FindB.cmake) diff --git a/test/unit/source_dir.cmake b/test/unit/source_dir.cmake index 664cc44..96441a1 100644 --- a/test/unit/source_dir.cmake +++ b/test/unit/source_dir.cmake @@ -4,15 +4,17 @@ 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}/source_dir/CMakeLists.txt.in" - "${CMAKE_CURRENT_LIST_DIR}/source_dir/CMakeLists.txt" + "${CMAKE_CURRENT_LIST_DIR}/test_project/CMakeLists.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}/source_dir" "-B${TEST_BUILD_DIR}" + ${CMAKE_COMMAND} "-H${CMAKE_CURRENT_LIST_DIR}/test_project" "-B${TEST_BUILD_DIR}" RESULT_VARIABLE ret ) diff --git a/test/unit/source_dir/.gitignore b/test/unit/test_project/.gitignore similarity index 100% rename from test/unit/source_dir/.gitignore rename to test/unit/test_project/.gitignore diff --git a/test/unit/source_dir/CMakeLists.txt.in b/test/unit/test_project/CMakeLists.txt.in similarity index 67% rename from test/unit/source_dir/CMakeLists.txt.in rename to test/unit/test_project/CMakeLists.txt.in index f4eb4d7..8724c60 100644 --- a/test/unit/source_dir/CMakeLists.txt.in +++ b/test/unit/test_project/CMakeLists.txt.in @@ -11,10 +11,16 @@ option(ENABLE_TEST_COVERAGE "Enable test coverage" OFF) include(@CPM_PATH@/CPM.cmake) CPMAddPackage( - NAME Dependency + NAME @TEST_DEPENDENCY_NAME@ SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/dependency ) +# ---- check if generated modules override find_package ---- + +if (@test_check_find_package@) + find_package(@TEST_DEPENDENCY_NAME@ REQUIRED) +endif() + # ---- Call dependency method to validate correct addition of directory ---- dependency_function() diff --git a/test/unit/source_dir/dependency/CMakeLists.txt b/test/unit/test_project/dependency/CMakeLists.txt similarity index 100% rename from test/unit/source_dir/dependency/CMakeLists.txt rename to test/unit/test_project/dependency/CMakeLists.txt