Use cmake modules inside a
When we want to reuse some
.cmake scripts that are inside another Conan package
there are several possible different scenarios, like if the
.cmake scripts are inside
requires or a
Also, it is possible to want 2 different approaches:
- The consumer of the scripts can do a explicit
include(MyScript)in their CMakeLists.txt. This approach is nicely explicit and simpler to setup, just define
self.cpp_info.builddirsin the recipe, and consumers with
CMakeToolchainwill automatically be able to do the
include()and use the functionality. See the example here
- The consumer wants to have the dependency cmake modules automatically loaded when the
find_package()is executed. This current example implements this case.
Let’s say that we have a package, intended to be used as a
tool_require, with the following recipe:
import os from conan import ConanFile from conan.tools.files import copy class Conan(ConanFile): name = "myfunctions" version = "1.0" exports_sources = ["*.cmake"] def package(self): copy(self, "*.cmake", self.source_folder, self.package_folder) def package_info(self): self.cpp_info.set_property("cmake_build_modules", ["myfunction.cmake"])
myfunction.cmake file in:
function(myfunction) message("Hello myfunction!!!!") endfunction()
We can do a
cd myfunctions && conan create . which will create the
myfunctions/1.0 package containing the cmake script.
Then, a consumer package will look like:
from conan import ConanFile from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain class Conan(ConanFile): settings = "os", "compiler", "build_type", "arch" tool_requires = "myfunctions/1.0" def generate(self): tc = CMakeToolchain(self) tc.generate() deps = CMakeDeps(self) # By default 'myfunctions-config.cmake' is not created for tool_requires # we need to explicitly activate it deps.build_context_activated = ["myfunctions"] # and we need to tell to automatically load 'myfunctions' modules deps.build_context_build_modules = ["myfunctions"] deps.generate() def build(self): cmake = CMake(self) cmake.configure()
cmake_minimum_required(VERSION 3.0) project(test) find_package(myfunctions CONFIG REQUIRED) myfunction()
Then, the consumer will be able to automatically call the
myfunction() from the dependency module:
$ conan build . ... Hello myfunction!!!!
If for some reason the consumer wants to force the usage from the
tool_requires() as a CMake module, the consumer could do
deps.set_property("myfunctions", "cmake_find_mode", "module", build_context=True), and then
find_package(myfunctions MODULE REQUIRED) will work.