Compare commits

...

4 Commits

Author SHA1 Message Date
Avus-c
c3807eb774 circumvent bug in cmake <3.30.3 (#605)
Co-authored-by: Avus <48911667+Avus@users.noreply.github.com>
2024-12-22 13:08:38 +01:00
Patrick Stewart
9ddfe1b6a8 Add find_package overrides that also work in CONFIG mode (#498) (#604) 2024-12-20 16:38:22 +01:00
Scott B
0bc73f41ce Additional search path for patch.exe (#581)
* Additional search path for patch.exe

* Style
2024-08-02 15:44:55 +02:00
Avus-c
8b67fe2344 replace deprecated calls to FetchContent_Populate (#570)
* replace deprecated calls to FetchContent_Populate

The single argument signature for FetchContent_Populate is deprecated with CMake 3.30.
It was used, in order to call add_subdirectory manually with the EXCLUDE_FROM_ALL and SYSTEM flags.
These have been added to FetchContent_Declare with 3.25 and 3.28.
Calling FetchContent_MakeAvailable will internally call add_subdirectory with EXCLUDE_FROM_ALL and SYSTEM.
There is therefore no need to call this manually.

* fix: OPTIONS passed to CPMAddPackage not set

where previously parsed in cpm_add_subdirectory which is not called
on the new code path.

* refactor: remove an unnecessary else branch

* ci: include cmake 3.30 in test matrix

* fix: forward SOURCE_SUBDIR to FetchContent_Declare

For CMake version <3.28 this is done by calling add_subdirectory manually.
For newer version FetchContent_Declare/MakeAvailable handles this for us.

* fix: only set options if download_only is false

this replicates the old behaviour

* fix: DOWNLOAD_ONLY test

* refactor: always use *_Populate to reduce code paths

* Revert "refactor: always use *_Populate to reduce code paths"

This reverts commit 0e8ca2a0e9.

---------

Co-authored-by: Avus <48911667+Avus@users.noreply.github.com>
2024-07-29 11:19:31 +02:00
6 changed files with 116 additions and 34 deletions

View File

@@ -19,7 +19,7 @@ jobs:
os: [ubuntu-latest, windows-2022, macos-latest] os: [ubuntu-latest, windows-2022, macos-latest]
# we want to ensure compatibility with a recent CMake version as well as the lowest officially supported # we want to ensure compatibility with a recent CMake version as well as the lowest officially supported
# legacy version that we define as the default version of the second-latest Ubuntu LTS release currently available # legacy version that we define as the default version of the second-latest Ubuntu LTS release currently available
cmake_version: ['3.16.3', '3.27.5'] cmake_version: ['3.16.3', '3.27.5', '3.30.0']
exclude: exclude:
# there seems to be an issue with CMake 3.16 not finding a C++ compiler on windows-2022 # there seems to be an issue with CMake 3.16 not finding a C++ compiler on windows-2022
- os: windows-2022 - os: windows-2022

View File

@@ -214,6 +214,13 @@ In the case that `find_package` requires additional arguments, the parameter `FI
Note that this does not apply to dependencies that have been defined with a truthy `FORCE` parameter. These will be added as defined. Note that this does not apply to dependencies that have been defined with a truthy `FORCE` parameter. These will be added as defined.
### CPM_DONT_UPDATE_MODULE_PATH
By default, CPM will override any `find_package` commands to use the CPM downloaded version.
This is equivalent to the `OVERRIDE_FIND_PACKAGE` FetchContent option, which has no effect in CPM.
To disable this behaviour set the `CPM_DONT_UPDATE_MODULE_PATH` option.
This will not work for `find_package(CONFIG)` in CMake versions before 3.24.
### CPM_USE_NAMED_CACHE_DIRECTORIES ### CPM_USE_NAMED_CACHE_DIRECTORIES
If set, CPM use additional directory level in cache to improve readability of packages names in IDEs like CLion. It changes cache structure, so all dependencies are downloaded again. There is no problem to mix both structures in one cache directory but then there may be 2 copies of some dependencies. If set, CPM use additional directory level in cache to improve readability of packages names in IDEs like CLion. It changes cache structure, so all dependencies are downloaded again. There is no problem to mix both structures in one cache directory but then there may be 2 copies of some dependencies.

View File

@@ -162,7 +162,7 @@ set(CPM_SOURCE_CACHE
CACHE PATH "Directory to download CPM dependencies" CACHE PATH "Directory to download CPM dependencies"
) )
if(NOT CPM_DONT_UPDATE_MODULE_PATH) if(NOT CPM_DONT_UPDATE_MODULE_PATH AND NOT DEFINED CMAKE_FIND_PACKAGE_REDIRECTS_DIR)
set(CPM_MODULE_PATH set(CPM_MODULE_PATH
"${CMAKE_BINARY_DIR}/CPM_modules" "${CMAKE_BINARY_DIR}/CPM_modules"
CACHE INTERNAL "" CACHE INTERNAL ""
@@ -269,10 +269,25 @@ endfunction()
# finding the system library # finding the system library
function(cpm_create_module_file Name) function(cpm_create_module_file Name)
if(NOT CPM_DONT_UPDATE_MODULE_PATH) if(NOT CPM_DONT_UPDATE_MODULE_PATH)
# erase any previous modules if(DEFINED CMAKE_FIND_PACKAGE_REDIRECTS_DIR)
file(WRITE ${CPM_MODULE_PATH}/Find${Name}.cmake # Redirect find_package calls to the CPM package. This is what FetchContent does when you set
"include(\"${CPM_FILE}\")\n${ARGN}\nset(${Name}_FOUND TRUE)" # OVERRIDE_FIND_PACKAGE. The CMAKE_FIND_PACKAGE_REDIRECTS_DIR works for find_package in CONFIG
) # mode, unlike the Find${Name}.cmake fallback. CMAKE_FIND_PACKAGE_REDIRECTS_DIR is not defined
# in script mode, or in CMake < 3.24.
# https://cmake.org/cmake/help/latest/module/FetchContent.html#fetchcontent-find-package-integration-examples
string(TOLOWER ${Name} NameLower)
file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/${NameLower}-config.cmake
"include(\"${CMAKE_CURRENT_LIST_DIR}/${NameLower}-extra.cmake\" OPTIONAL)\n"
"include(\"${CMAKE_CURRENT_LIST_DIR}/${Name}Extra.cmake\" OPTIONAL)\n"
)
file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/${NameLower}-version.cmake
"set(PACKAGE_VERSION_COMPATIBLE TRUE)\n" "set(PACKAGE_VERSION_EXACT TRUE)\n"
)
else()
file(WRITE ${CPM_MODULE_PATH}/Find${Name}.cmake
"include(\"${CPM_FILE}\")\n${ARGN}\nset(${Name}_FOUND TRUE)"
)
endif()
endif() endif()
endfunction() endfunction()
@@ -477,13 +492,16 @@ function(cpm_add_patches)
find_program(PATCH_EXECUTABLE patch) find_program(PATCH_EXECUTABLE patch)
if(WIN32 AND NOT PATCH_EXECUTABLE) if(WIN32 AND NOT PATCH_EXECUTABLE)
# The Windows git executable is distributed with patch.exe. Find the path to the executable, if # The Windows git executable is distributed with patch.exe. Find the path to the executable, if
# it exists, then search `../../usr/bin` for patch.exe. # it exists, then search `../usr/bin` and `../../usr/bin` for patch.exe.
find_package(Git QUIET) find_package(Git QUIET)
if(GIT_EXECUTABLE) if(GIT_EXECUTABLE)
get_filename_component(extra_search_path ${GIT_EXECUTABLE} DIRECTORY) get_filename_component(extra_search_path ${GIT_EXECUTABLE} DIRECTORY)
get_filename_component(extra_search_path ${extra_search_path} DIRECTORY) get_filename_component(extra_search_path_1up ${extra_search_path} DIRECTORY)
get_filename_component(extra_search_path ${extra_search_path} DIRECTORY) get_filename_component(extra_search_path_2up ${extra_search_path_1up} DIRECTORY)
find_program(PATCH_EXECUTABLE patch HINTS "${extra_search_path}/usr/bin") find_program(
PATCH_EXECUTABLE patch HINTS "${extra_search_path_1up}/usr/bin"
"${extra_search_path_2up}/usr/bin"
)
endif() endif()
endif() endif()
if(NOT PATCH_EXECUTABLE) if(NOT PATCH_EXECUTABLE)
@@ -862,14 +880,39 @@ function(CPMAddPackage)
) )
if(NOT CPM_SKIP_FETCH) if(NOT CPM_SKIP_FETCH)
# CMake 3.28 added EXCLUDE, SYSTEM (3.25), and SOURCE_SUBDIR (3.18) to FetchContent_Declare.
# Calling FetchContent_MakeAvailable will then internally forward these options to
# add_subdirectory. Up until these changes, we had to call FetchContent_Populate and
# add_subdirectory separately, which is no longer necessary and has been deprecated as of 3.30.
# A Bug in CMake prevents us to use the non-deprecated functions until 3.30.3.
set(fetchContentDeclareExtraArgs "")
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.30.3")
if(${CPM_ARGS_EXCLUDE_FROM_ALL})
list(APPEND fetchContentDeclareExtraArgs EXCLUDE_FROM_ALL)
endif()
if(${CPM_ARGS_SYSTEM})
list(APPEND fetchContentDeclareExtraArgs SYSTEM)
endif()
if(DEFINED CPM_ARGS_SOURCE_SUBDIR)
list(APPEND fetchContentDeclareExtraArgs SOURCE_SUBDIR ${CPM_ARGS_SOURCE_SUBDIR})
endif()
# For CMake version <3.28 OPTIONS are parsed in cpm_add_subdirectory
if(CPM_ARGS_OPTIONS AND NOT DOWNLOAD_ONLY)
foreach(OPTION ${CPM_ARGS_OPTIONS})
cpm_parse_option("${OPTION}")
set(${OPTION_KEY} "${OPTION_VALUE}")
endforeach()
endif()
endif()
cpm_declare_fetch( cpm_declare_fetch(
"${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}" "${PACKAGE_INFO}" "${CPM_ARGS_UNPARSED_ARGUMENTS}" "${CPM_ARGS_NAME}" ${fetchContentDeclareExtraArgs} "${CPM_ARGS_UNPARSED_ARGUMENTS}"
) )
cpm_fetch_package("${CPM_ARGS_NAME}" populated)
cpm_fetch_package("${CPM_ARGS_NAME}" ${DOWNLOAD_ONLY} populated ${CPM_ARGS_UNPARSED_ARGUMENTS})
if(CPM_SOURCE_CACHE AND download_directory) if(CPM_SOURCE_CACHE AND download_directory)
file(LOCK ${download_directory}/../cmake.lock RELEASE) file(LOCK ${download_directory}/../cmake.lock RELEASE)
endif() endif()
if(${populated}) if(${populated} AND ${CMAKE_VERSION} VERSION_LESS "3.30.3")
cpm_add_subdirectory( cpm_add_subdirectory(
"${CPM_ARGS_NAME}" "${CPM_ARGS_NAME}"
"${DOWNLOAD_ONLY}" "${DOWNLOAD_ONLY}"
@@ -980,7 +1023,7 @@ function(CPMGetPackageVersion PACKAGE OUTPUT)
endfunction() endfunction()
# declares a package in FetchContent_Declare # declares a package in FetchContent_Declare
function(cpm_declare_fetch PACKAGE VERSION INFO) function(cpm_declare_fetch PACKAGE)
if(${CPM_DRY_RUN}) if(${CPM_DRY_RUN})
cpm_message(STATUS "${CPM_INDENT} Package not declared (dry run)") cpm_message(STATUS "${CPM_INDENT} Package not declared (dry run)")
return() return()
@@ -1056,7 +1099,7 @@ endfunction()
# downloads a previously declared package via FetchContent and exports the variables # downloads a previously declared package via FetchContent and exports the variables
# `${PACKAGE}_SOURCE_DIR` and `${PACKAGE}_BINARY_DIR` to the parent scope # `${PACKAGE}_SOURCE_DIR` and `${PACKAGE}_BINARY_DIR` to the parent scope
function(cpm_fetch_package PACKAGE populated) function(cpm_fetch_package PACKAGE DOWNLOAD_ONLY populated)
set(${populated} set(${populated}
FALSE FALSE
PARENT_SCOPE PARENT_SCOPE
@@ -1071,7 +1114,24 @@ function(cpm_fetch_package PACKAGE populated)
string(TOLOWER "${PACKAGE}" lower_case_name) string(TOLOWER "${PACKAGE}" lower_case_name)
if(NOT ${lower_case_name}_POPULATED) if(NOT ${lower_case_name}_POPULATED)
FetchContent_Populate(${PACKAGE}) if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.30.3")
if(DOWNLOAD_ONLY)
# MakeAvailable will call add_subdirectory internally which is not what we want when
# DOWNLOAD_ONLY is set. Populate will only download the dependency without adding it to the
# build
FetchContent_Populate(
${PACKAGE}
SOURCE_DIR "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-src"
BINARY_DIR "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-build"
SUBBUILD_DIR "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-subbuild"
${ARGN}
)
else()
FetchContent_MakeAvailable(${PACKAGE})
endif()
else()
FetchContent_Populate(${PACKAGE})
endif()
set(${populated} set(${populated}
TRUE TRUE
PARENT_SCOPE PARENT_SCOPE

View File

@@ -31,7 +31,9 @@ class Basics < IntegrationTest
assert_same_path File.join(prj.bin_dir, 'cpm-package-lock.cmake'), check_and_get('CPM_PACKAGE_LOCK_FILE') assert_same_path File.join(prj.bin_dir, 'cpm-package-lock.cmake'), check_and_get('CPM_PACKAGE_LOCK_FILE')
assert_equal 'OFF', check_and_get('CPM_DONT_UPDATE_MODULE_PATH', 'BOOL') assert_equal 'OFF', check_and_get('CPM_DONT_UPDATE_MODULE_PATH', 'BOOL')
assert_same_path File.join(prj.bin_dir, 'CPM_modules'), check_and_get('CPM_MODULE_PATH') if @cache.entries['CMAKE_FIND_PACKAGE_REDIRECTS_DIR'].nil?
assert_same_path File.join(prj.bin_dir, 'CPM_modules'), check_and_get('CPM_MODULE_PATH')
end
end end
# Test when env CPM_SOURCE_CACHE is set # Test when env CPM_SOURCE_CACHE is set

View File

@@ -8,6 +8,10 @@ option(ENABLE_TEST_COVERAGE "Enable test coverage" OFF)
# ---- Dependencies ---- # ---- Dependencies ----
if (@TEST_FORCE_MODULE_MODE@)
unset(CMAKE_FIND_PACKAGE_REDIRECTS_DIR CACHE)
endif()
include(@CPM_PATH@/CPM.cmake) include(@CPM_PATH@/CPM.cmake)
CPMAddPackage( CPMAddPackage(
@@ -15,21 +19,23 @@ CPMAddPackage(
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/dependency 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 ---- # ---- Call dependency method to validate correct addition of directory ----
dependency_function() dependency_function()
# ---- Check parameters ---- # ---- Check newly added ----
include(@CPM_PATH@/testing.cmake) include(@CPM_PATH@/testing.cmake)
ASSERT_TRUTHY(@TEST_DEPENDENCY_NAME@_ADDED) ASSERT_TRUTHY(@TEST_DEPENDENCY_NAME@_ADDED)
# ---- Check if generated modules override find_package ----
if (@TEST_FIND_PACKAGE@)
find_package(@TEST_DEPENDENCY_NAME@ @TEST_FIND_PACKAGE_CONFIG@ REQUIRED)
find_package(@TEST_CANT_FIND_PACKAGE_NAME@ @TEST_FIND_PACKAGE_CONFIG@ QUIET)
ASSERT_FALSY(@TEST_CANT_FIND_PACKAGE_NAME@_FOUND)
endif()
# ---- Check parameters ----
ASSERT_DEFINED(@TEST_DEPENDENCY_NAME@_SOURCE_DIR) ASSERT_DEFINED(@TEST_DEPENDENCY_NAME@_SOURCE_DIR)
ASSERT_DEFINED(@TEST_DEPENDENCY_NAME@_BINARY_DIR) ASSERT_DEFINED(@TEST_DEPENDENCY_NAME@_BINARY_DIR)
ASSERT_EQUAL("${CPM_LAST_PACKAGE_NAME}" "@TEST_DEPENDENCY_NAME@") ASSERT_EQUAL("${CPM_LAST_PACKAGE_NAME}" "@TEST_DEPENDENCY_NAME@")

View File

@@ -3,7 +3,8 @@ include(${CPM_PATH}/testing.cmake)
set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/modules) set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/modules)
function(init_project_with_dependency TEST_DEPENDENCY_NAME) function(init_project_with_dependency TEST_DEPENDENCY_NAME TEST_CANT_FIND_PACKAGE_NAME)
set(TEST_FIND_PACKAGE ON)
configure_package_config_file( configure_package_config_file(
"${CMAKE_CURRENT_LIST_DIR}/local_dependency/ModuleCMakeLists.txt.in" "${CMAKE_CURRENT_LIST_DIR}/local_dependency/ModuleCMakeLists.txt.in"
"${CMAKE_CURRENT_LIST_DIR}/local_dependency/CMakeLists.txt" "${CMAKE_CURRENT_LIST_DIR}/local_dependency/CMakeLists.txt"
@@ -18,11 +19,17 @@ function(init_project_with_dependency TEST_DEPENDENCY_NAME)
assert_equal(${ret} "0") assert_equal(${ret} "0")
endfunction() endfunction()
init_project_with_dependency(A) init_project_with_dependency(A B)
assert_exists(${TEST_BUILD_DIR}/CPM_modules) init_project_with_dependency(B A)
assert_exists(${TEST_BUILD_DIR}/CPM_modules/FindA.cmake)
assert_not_exists(${TEST_BUILD_DIR}/CPM_modules/FindB.cmake)
init_project_with_dependency(B) if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.24.0")
assert_not_exists(${TEST_BUILD_DIR}/CPM_modules/FindA.cmake) set(TEST_FIND_PACKAGE_CONFIG CONFIG)
assert_exists(${TEST_BUILD_DIR}/CPM_modules/FindB.cmake) init_project_with_dependency(A B)
init_project_with_dependency(B A)
# Test the fallback path for CMake <3.24 works
set(TEST_FIND_PACKAGE_CONFIG)
set(TEST_FORCE_MODULE_MODE ON)
init_project_with_dependency(A B)
init_project_with_dependency(B A)
endif()