Add dependencies to packages

In the previous tutorial section we created a Conan package for a “Hello World” C++ library. We used the conan.tools.scm.Git() tool to retrieve the sources from a git repository. So far, the package does not have any dependency on other Conan packages. Let’s explain how to add a dependency to our package in a very similar way to how we did in the consuming packages section. We will add some fancy colour output to our “Hello World” library using the fmt library.

Please, first clone the sources to recreate this project. You can find them in the examples2 repository on GitHub:

$ git clone https://github.com/conan-io/examples2.git
$ cd examples2/tutorial/creating_packages/add_requires

You will notice some changes in the conanfile.py file from the previous recipe. Let’s check the relevant parts:

...
from conan.tools.build import check_max_cppstd, check_min_cppstd
...

class helloRecipe(ConanFile):
    name = "hello"
    version = "1.0"

    ...
    generators = "CMakeDeps"
    ...

    def validate(self):
        check_min_cppstd(self, "11")
        check_max_cppstd(self, "20")

    def requirements(self):
        self.requires("fmt/8.1.1")

    def source(self):
        git = Git(self)
        git.clone(url="https://github.com/conan-io/libhello.git", target=".")
        # Please, be aware that using the head of the branch instead of an immutable tag
        # or commit is not a good practice in general
        git.checkout("require_fmt")
  • First, we set the generators class attribute to make Conan invoke the CMakeDeps generator. This was not needed in the previous recipe as we did not have dependencies. CMakeDeps will generate all the config files CMake needs to find the fmt library.

  • Next, we use the requires() method to add the fmt dependency to our package.

  • Also, check that we added an extra line in the source() method. We use the Git().checkout method to checkout the source code in the require_fmt branch. This branch contains the changes in the source code to add colours to the library messages, and also in the CMakeLists.txt to declare that we are using the fmt library.

  • Finally, note we added the validate() method to the recipe. We already used this method in the consuming packages section to raise an error for non-supported configurations. Here, we call the check_min_cppstd() and check_max_cppstd() to check that we are using at least C++11 and at most C++20 standards in our settings.

You can check the new sources, using the fmt library in the require_fmt. You will see that the hello.cpp file adds colours to the output messages:

#include <fmt/color.h>

#include "hello.h"

void hello(){
    #ifdef NDEBUG
    fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold, "hello/1.0: Hello World Release!\n");
    #else
    fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold, "hello/1.0: Hello World Debug!\n");
    #endif
    ...

Let’s build the package from sources with the current default configuration, and then let the test_package folder test the package. You should see the output messages with colour now:

$ conan create . --build=missing
-------- Exporting the recipe ----------
...
-------- Testing the package: Running test() ----------
hello/1.0 (test package): Running test()
hello/1.0 (test package): RUN: ./example
hello/1.0: Hello World Release!
  hello/1.0: __x86_64__ defined
  hello/1.0: __cplusplus 201103
  hello/1.0: __GNUC__ 4
  hello/1.0: __GNUC_MINOR__ 2
  hello/1.0: __clang_major__ 13
  hello/1.0: __clang_minor__ 1
  hello/1.0: __apple_build_version__ 13160021