Skip to content

Commit

Permalink
conan-provider.cmake: introduce a new policy scope, set min cmake ver…
Browse files Browse the repository at this point in the history
…sion (#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 <[email protected]>
  • Loading branch information
xmkg authored Jun 24, 2024
1 parent 8036ecf commit 24e91d6
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
14 changes: 14 additions & 0 deletions conan_provider.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@

set(CONAN_MINIMUM_VERSION 2.0.5)

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

function(detect_os OS OS_API_LEVEL OS_SDK OS_SUBSYSTEM OS_VERSION)
# it could be cross compilation
Expand Down Expand Up @@ -647,3 +659,5 @@ if(NOT _cmake_program)
get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY)
set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is")
endif()

cmake_policy(POP)
21 changes: 21 additions & 0 deletions tests/resources/find_module/policy_scope/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.0)
project(MyApp CXX)

set(CMAKE_CXX_STANDARD 17)
find_package(hello REQUIRED)
# Request that Findbye.cmake (generated by Conan)
# is used instead of bye-config.cmake
find_package(bye MODULE REQUIRED)

# The `find_package` will include the conan_provider.cmake file
# which has policy-affecting code. We expect no changes to the current
# policy scope.

add_executable(app main.cpp)
target_link_libraries(app hello::hello bye::bye)

set(test_list a b c d e f)
if("a" IN_LIST test_list)
# see https://cmake.org/cmake/help/latest/policy/CMP0057.html
message(ERROR "this should not happen as IN_LIST is a CMake 3.3 feature.")
endif()
17 changes: 17 additions & 0 deletions tests/test_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,23 @@ def test_cmake_builtin_module(self, capfd, basic_cmake_project):
out, _ = capfd.readouterr()
assert "Found Threads: TRUE" in out

def test_policy_scope(self, capfd, basic_cmake_project):
"""
Ensure that the policy settings of the user project is not affected by the
"module's policy-affecting calls.
"""
source_dir, binary_dir = basic_cmake_project
shutil.copytree(resources_dir / 'find_module' / 'policy_scope', source_dir, dirs_exist_ok=True)

run(f"cmake -S {source_dir} -B {binary_dir} -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES={conan_provider} -DCMAKE_BUILD_TYPE=Release", check=False)
out, err = capfd.readouterr()
assert not re.search(rf'CMake Error at {re.escape(str(conan_provider))}.*\(if\):\n if given arguments', err)
assert "Conan: Target declared 'hello::hello'" in out
assert "Conan: Target declared 'bye::bye'" in out
assert "\"a\" \"IN_LIST\" \"test_list\"" in err
assert "this should not happen as IN_LIST is a CMake 3.3 feature." not in err



class TestCMakeModulePath:

Expand Down

0 comments on commit 24e91d6

Please sign in to comment.