diff --git a/conan/tools/cmake/base.py b/conan/tools/cmake/base.py index 61af6c79c91..5e9473b2f88 100644 --- a/conan/tools/cmake/base.py +++ b/conan/tools/cmake/base.py @@ -85,6 +85,9 @@ class CMakeToolchainBase(object): # We are going to adjust automagically many things as requested by Conan # these are the things done by 'conan_basic_setup()' set(CMAKE_EXPORT_NO_PACKAGE_REGISTRY ON) + {%- if find_package_prefer_config %} + set(CMAKE_FIND_PACKAGE_PREFER_CONFIG {{ find_package_prefer_config }}) + {%- endif %} # To support the cmake_find_package generators {% if cmake_module_path -%} set(CMAKE_MODULE_PATH {{ cmake_module_path }} ${CMAKE_MODULE_PATH}) @@ -133,6 +136,8 @@ class CMakeToolchainBase(object): """) def __init__(self, conanfile, **kwargs): + import six + self._conanfile = conanfile self.variables = Variables() self.preprocessor_definitions = Variables() @@ -143,6 +148,12 @@ def __init__(self, conanfile, **kwargs): self.build_type = None + self.find_package_prefer_config = \ + conanfile.conf["tools.cmake.cmaketoolchain"].find_package_prefer_config + if self.find_package_prefer_config is not None: + self.find_package_prefer_config = "OFF" if self.find_package_prefer_config.lower() in ("false", "0", "off") else "ON" + else: + self.find_package_prefer_config = "ON" # assume ON by default if not specified in conf def _get_templates(self): return { 'toolchain_macros': self._toolchain_macros_tpl, @@ -160,6 +171,7 @@ def _get_template_context_data(self): "cmake_prefix_path": self.cmake_prefix_path, "cmake_module_path": self.cmake_module_path, "build_type": self.build_type, + "find_package_prefer_config": self.find_package_prefer_config, } return ctxt_toolchain diff --git a/conans/test/functional/toolchains/cmake/test_cmake.py b/conans/test/functional/toolchains/cmake/test_cmake.py index 3d52429a500..8f3fa69d7c6 100644 --- a/conans/test/functional/toolchains/cmake/test_cmake.py +++ b/conans/test/functional/toolchains/cmake/test_cmake.py @@ -516,3 +516,59 @@ def build(self): client.run("install .") client.run("build .") self.assertIn("VALUE OF CONFIG STRING: my new value", client.out) + + +@pytest.mark.toolchain +@pytest.mark.tool_cmake +class CMakeFindPackagePreferConfigTest(unittest.TestCase): + + @parameterized.expand([(True,), (False,)]) + def test_prefer_config(self, prefer_config): + conanfile = textwrap.dedent(""" + from conans import ConanFile + from conan.tools.cmake import CMake, CMakeToolchain + class App(ConanFile): + settings = "os", "arch", "compiler", "build_type" + exports_sources = "CMakeLists.txt" + def generate(self): + toolchain = CMakeToolchain(self) + toolchain.generate() + def build(self): + cmake = CMake(self) + cmake.configure() + """) + + cmakelist = textwrap.dedent(""" + cmake_minimum_required(VERSION 3.15) + project(my_project) + find_package(Comandante REQUIRED) + """) + + find = textwrap.dedent(""" + message(STATUS "using FindComandante.cmake") + """) + + config = textwrap.dedent(""" + message(STATUS "using ComandanteConfig.cmake") + """) + + profile = textwrap.dedent(""" + include(default) + [conf] + tools.cmake.cmaketoolchain:find_package_prefer_config={} + """).format(prefer_config) + + client = TestClient() + client.save({"conanfile.py": conanfile, + "CMakeLists.txt": cmakelist, + "FindComandante.cmake": find, + "ComandanteConfig.cmake": config, + "profile": profile}) + + client.run("install . --profile profile") + client.run("build .") + + if prefer_config: + self.assertIn("using ComandanteConfig.cmake", client.out) + else: + self.assertIn("using FindComandante.cmake", client.out)