Skip to content

Commit 24e91d6

Browse files
authored
conan-provider.cmake: introduce a new policy scope, set min cmake version (#645)
cmake has the notion of "policy scopes" to limit the scope of the policies. this patch introduces a module-level policy scope and sets the minimum required cmake version to 3.24, so the cmake features depend on policy settings such as `if(... IN_LIST ...)` behaves as expected even if the consuming project does not declare a cmake minimum version requirement. also, this change now enforces the version requirement so the code would fail immediately if the cmake version is less than the minimum. Signed-off-by: Mustafa Kemal Gilor <hello@mkg.dev>
1 parent 8036ecf commit 24e91d6

3 files changed

Lines changed: 52 additions & 0 deletions

File tree

conan_provider.cmake

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@
2222

2323
set(CONAN_MINIMUM_VERSION 2.0.5)
2424

25+
# Create a new policy scope and set the minimum required cmake version so the
26+
# features behind a policy setting like if(... IN_LIST ...) behaves as expected
27+
# even if the parent project does not specify a minimum cmake version or a minimum
28+
# version less than this module requires (e.g. 3.0) before the first project() call.
29+
# (see: https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.html)
30+
#
31+
# The policy-affecting calls like cmake_policy(SET...) or `cmake_minimum_required` only
32+
# affects the current policy scope, i.e. between the PUSH and POP in this case.
33+
#
34+
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Policies.html#the-policy-stack
35+
cmake_policy(PUSH)
36+
cmake_minimum_required(VERSION 3.24)
2537

2638
function(detect_os OS OS_API_LEVEL OS_SDK OS_SUBSYSTEM OS_VERSION)
2739
# it could be cross compilation
@@ -647,3 +659,5 @@ if(NOT _cmake_program)
647659
get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY)
648660
set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is")
649661
endif()
662+
663+
cmake_policy(POP)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
cmake_minimum_required(VERSION 3.0)
2+
project(MyApp CXX)
3+
4+
set(CMAKE_CXX_STANDARD 17)
5+
find_package(hello REQUIRED)
6+
# Request that Findbye.cmake (generated by Conan)
7+
# is used instead of bye-config.cmake
8+
find_package(bye MODULE REQUIRED)
9+
10+
# The `find_package` will include the conan_provider.cmake file
11+
# which has policy-affecting code. We expect no changes to the current
12+
# policy scope.
13+
14+
add_executable(app main.cpp)
15+
target_link_libraries(app hello::hello bye::bye)
16+
17+
set(test_list a b c d e f)
18+
if("a" IN_LIST test_list)
19+
# see https://cmake.org/cmake/help/latest/policy/CMP0057.html
20+
message(ERROR "this should not happen as IN_LIST is a CMake 3.3 feature.")
21+
endif()

tests/test_smoke.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,23 @@ def test_cmake_builtin_module(self, capfd, basic_cmake_project):
277277
out, _ = capfd.readouterr()
278278
assert "Found Threads: TRUE" in out
279279

280+
def test_policy_scope(self, capfd, basic_cmake_project):
281+
"""
282+
Ensure that the policy settings of the user project is not affected by the
283+
"module's policy-affecting calls.
284+
"""
285+
source_dir, binary_dir = basic_cmake_project
286+
shutil.copytree(resources_dir / 'find_module' / 'policy_scope', source_dir, dirs_exist_ok=True)
287+
288+
run(f"cmake -S {source_dir} -B {binary_dir} -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES={conan_provider} -DCMAKE_BUILD_TYPE=Release", check=False)
289+
out, err = capfd.readouterr()
290+
assert not re.search(rf'CMake Error at {re.escape(str(conan_provider))}.*\(if\):\n if given arguments', err)
291+
assert "Conan: Target declared 'hello::hello'" in out
292+
assert "Conan: Target declared 'bye::bye'" in out
293+
assert "\"a\" \"IN_LIST\" \"test_list\"" in err
294+
assert "this should not happen as IN_LIST is a CMake 3.3 feature." not in err
295+
296+
280297

281298
class TestCMakeModulePath:
282299

0 commit comments

Comments
 (0)