Skip to content

Commit 9ddfe1b

Browse files
authored
Add find_package overrides that also work in CONFIG mode (#498) (#604)
1 parent 0bc73f4 commit 9ddfe1b

File tree

5 files changed

+60
-23
lines changed

5 files changed

+60
-23
lines changed

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,13 @@ In the case that `find_package` requires additional arguments, the parameter `FI
214214

215215
Note that this does not apply to dependencies that have been defined with a truthy `FORCE` parameter. These will be added as defined.
216216

217+
### CPM_DONT_UPDATE_MODULE_PATH
218+
219+
By default, CPM will override any `find_package` commands to use the CPM downloaded version.
220+
This is equivalent to the `OVERRIDE_FIND_PACKAGE` FetchContent option, which has no effect in CPM.
221+
To disable this behaviour set the `CPM_DONT_UPDATE_MODULE_PATH` option.
222+
This will not work for `find_package(CONFIG)` in CMake versions before 3.24.
223+
217224
### CPM_USE_NAMED_CACHE_DIRECTORIES
218225

219226
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.

cmake/CPM.cmake

+20-5
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ set(CPM_SOURCE_CACHE
162162
CACHE PATH "Directory to download CPM dependencies"
163163
)
164164

165-
if(NOT CPM_DONT_UPDATE_MODULE_PATH)
165+
if(NOT CPM_DONT_UPDATE_MODULE_PATH AND NOT DEFINED CMAKE_FIND_PACKAGE_REDIRECTS_DIR)
166166
set(CPM_MODULE_PATH
167167
"${CMAKE_BINARY_DIR}/CPM_modules"
168168
CACHE INTERNAL ""
@@ -269,10 +269,25 @@ endfunction()
269269
# finding the system library
270270
function(cpm_create_module_file Name)
271271
if(NOT CPM_DONT_UPDATE_MODULE_PATH)
272-
# erase any previous modules
273-
file(WRITE ${CPM_MODULE_PATH}/Find${Name}.cmake
274-
"include(\"${CPM_FILE}\")\n${ARGN}\nset(${Name}_FOUND TRUE)"
275-
)
272+
if(DEFINED CMAKE_FIND_PACKAGE_REDIRECTS_DIR)
273+
# Redirect find_package calls to the CPM package. This is what FetchContent does when you set
274+
# OVERRIDE_FIND_PACKAGE. The CMAKE_FIND_PACKAGE_REDIRECTS_DIR works for find_package in CONFIG
275+
# mode, unlike the Find${Name}.cmake fallback. CMAKE_FIND_PACKAGE_REDIRECTS_DIR is not defined
276+
# in script mode, or in CMake < 3.24.
277+
# https://cmake.org/cmake/help/latest/module/FetchContent.html#fetchcontent-find-package-integration-examples
278+
string(TOLOWER ${Name} NameLower)
279+
file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/${NameLower}-config.cmake
280+
"include(\"${CMAKE_CURRENT_LIST_DIR}/${NameLower}-extra.cmake\" OPTIONAL)\n"
281+
"include(\"${CMAKE_CURRENT_LIST_DIR}/${Name}Extra.cmake\" OPTIONAL)\n"
282+
)
283+
file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/${NameLower}-version.cmake
284+
"set(PACKAGE_VERSION_COMPATIBLE TRUE)\n" "set(PACKAGE_VERSION_EXACT TRUE)\n"
285+
)
286+
else()
287+
file(WRITE ${CPM_MODULE_PATH}/Find${Name}.cmake
288+
"include(\"${CPM_FILE}\")\n${ARGN}\nset(${Name}_FOUND TRUE)"
289+
)
290+
endif()
276291
endif()
277292
endfunction()
278293

test/integration/test_basics.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ def test_cpm_default
3131
assert_same_path File.join(prj.bin_dir, 'cpm-package-lock.cmake'), check_and_get('CPM_PACKAGE_LOCK_FILE')
3232

3333
assert_equal 'OFF', check_and_get('CPM_DONT_UPDATE_MODULE_PATH', 'BOOL')
34-
assert_same_path File.join(prj.bin_dir, 'CPM_modules'), check_and_get('CPM_MODULE_PATH')
34+
if @cache.entries['CMAKE_FIND_PACKAGE_REDIRECTS_DIR'].nil?
35+
assert_same_path File.join(prj.bin_dir, 'CPM_modules'), check_and_get('CPM_MODULE_PATH')
36+
end
3537
end
3638

3739
# Test when env CPM_SOURCE_CACHE is set

test/unit/local_dependency/ModuleCMakeLists.txt.in

+15-9
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,34 @@ option(ENABLE_TEST_COVERAGE "Enable test coverage" OFF)
88

99
# ---- Dependencies ----
1010

11+
if (@TEST_FORCE_MODULE_MODE@)
12+
unset(CMAKE_FIND_PACKAGE_REDIRECTS_DIR CACHE)
13+
endif()
14+
1115
include(@CPM_PATH@/CPM.cmake)
1216

1317
CPMAddPackage(
1418
NAME @TEST_DEPENDENCY_NAME@
1519
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/dependency
1620
)
1721

18-
# ---- check if generated modules override find_package ----
19-
20-
if (@test_check_find_package@)
21-
find_package(@TEST_DEPENDENCY_NAME@ REQUIRED)
22-
endif()
23-
2422
# ---- Call dependency method to validate correct addition of directory ----
2523

2624
dependency_function()
2725

28-
# ---- Check parameters ----
29-
26+
# ---- Check newly added ----
3027
include(@CPM_PATH@/testing.cmake)
31-
3228
ASSERT_TRUTHY(@TEST_DEPENDENCY_NAME@_ADDED)
29+
30+
# ---- Check if generated modules override find_package ----
31+
32+
if (@TEST_FIND_PACKAGE@)
33+
find_package(@TEST_DEPENDENCY_NAME@ @TEST_FIND_PACKAGE_CONFIG@ REQUIRED)
34+
find_package(@TEST_CANT_FIND_PACKAGE_NAME@ @TEST_FIND_PACKAGE_CONFIG@ QUIET)
35+
ASSERT_FALSY(@TEST_CANT_FIND_PACKAGE_NAME@_FOUND)
36+
endif()
37+
38+
# ---- Check parameters ----
3339
ASSERT_DEFINED(@TEST_DEPENDENCY_NAME@_SOURCE_DIR)
3440
ASSERT_DEFINED(@TEST_DEPENDENCY_NAME@_BINARY_DIR)
3541
ASSERT_EQUAL("${CPM_LAST_PACKAGE_NAME}" "@TEST_DEPENDENCY_NAME@")

test/unit/modules.cmake

+15-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ include(${CPM_PATH}/testing.cmake)
33

44
set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/modules)
55

6-
function(init_project_with_dependency TEST_DEPENDENCY_NAME)
6+
function(init_project_with_dependency TEST_DEPENDENCY_NAME TEST_CANT_FIND_PACKAGE_NAME)
7+
set(TEST_FIND_PACKAGE ON)
78
configure_package_config_file(
89
"${CMAKE_CURRENT_LIST_DIR}/local_dependency/ModuleCMakeLists.txt.in"
910
"${CMAKE_CURRENT_LIST_DIR}/local_dependency/CMakeLists.txt"
@@ -18,11 +19,17 @@ function(init_project_with_dependency TEST_DEPENDENCY_NAME)
1819
assert_equal(${ret} "0")
1920
endfunction()
2021

21-
init_project_with_dependency(A)
22-
assert_exists(${TEST_BUILD_DIR}/CPM_modules)
23-
assert_exists(${TEST_BUILD_DIR}/CPM_modules/FindA.cmake)
24-
assert_not_exists(${TEST_BUILD_DIR}/CPM_modules/FindB.cmake)
22+
init_project_with_dependency(A B)
23+
init_project_with_dependency(B A)
2524

26-
init_project_with_dependency(B)
27-
assert_not_exists(${TEST_BUILD_DIR}/CPM_modules/FindA.cmake)
28-
assert_exists(${TEST_BUILD_DIR}/CPM_modules/FindB.cmake)
25+
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.24.0")
26+
set(TEST_FIND_PACKAGE_CONFIG CONFIG)
27+
init_project_with_dependency(A B)
28+
init_project_with_dependency(B A)
29+
30+
# Test the fallback path for CMake <3.24 works
31+
set(TEST_FIND_PACKAGE_CONFIG)
32+
set(TEST_FORCE_MODULE_MODE ON)
33+
init_project_with_dependency(A B)
34+
init_project_with_dependency(B A)
35+
endif()

0 commit comments

Comments
 (0)