Use a CMake macro packaged in a dependency

When a package recipe wants to provide a CMake functionality via a macro, it can be done as follows. Let’s say that we have a pkg recipe, that will “export” and “package” a Macros.cmake file that contains a pkg_macro() CMake macro:

pkg/conanfile.py

  1. from conan import ConanFile
  2. from conan.tools.files import copy
  3. class Pkg(ConanFile):
  4. name = "pkg"
  5. version = "0.1"
  6. package_type = "static-library"
  7. # Exporting, as part of the sources
  8. exports_sources = "*.cmake"
  9. def package(self):
  10. # Make sure the Macros.cmake is packaged
  11. copy(self, "*.cmake", src=self.source_folder, dst=self.package_folder)
  12. def package_info(self):
  13. # We need to define that there are "build-directories", in this case
  14. # the current package root folder, containing build files and scripts
  15. self.cpp_info.builddirs = ["."]

pkg/Macros.cmake

  1. function(pkg_macro)
  2. message(STATUS "PKG MACRO WORKING!!!")
  3. endfunction()

When this package is created (cd pkg && conan create .), it can be consumed by other package recipes, for example this application:

app/conanfile.py

  1. from conan import ConanFile
  2. from conan.tools.cmake import CMake
  3. class App(ConanFile):
  4. package_type = "application"
  5. generators = "CMakeToolchain"
  6. settings = "os", "compiler", "arch", "build_type"
  7. requires = "pkg/0.1"
  8. def build(self):
  9. cmake = CMake(self)
  10. cmake.configure()
  11. cmake.build()

That has this CMakeLists.txt:

app/CMakeLists.txt

  1. cmake_minimum_required(VERSION 3.15)
  2. project(App LANGUAGES NONE)
  3. include(Macros) # include the file with the macro (note no .cmake extension)
  4. pkg_macro() # call the macro

So when we run a local build, we will see how the file is included and the macro called:

  1. $ cd app
  2. $ conan build .
  3. PKG MACRO WORKING!!!