Skip to main content
Finding dependencies
"Modern CMake" course developed by Fergus Cooper and the Oxford Research Software Engineering group

"Modern CMake" course developed by Fergus Cooper and the Oxford Research Software Engineering group

Creative Commons License

Finding dependencies

Finding dependencies

Libraries can be installed in various locations on your system. CMake makes it easy to link against libraries without having to know where they are installed:
find_package(library_name CONFIG REQUIRED)
The above defines a new target that can now be linked against other targets using target_link_libraries. The target is usually namespaced, of the form Package::Component or Package::Package, for instance Eigen3::Eigen.

"config" mode for find_package

In "config mode", find_package will search for a <PackageName>Config.cmake file.
This file specifies all the information CMake needs (particularly where the library is installed).
This is usually given by the library vendor.
These files are installed alongside the libraries themselves, so you can see what your own system already provides. On a Debian-based system, most of them live under /usr/lib/x86_64-linux-gnu/cmake/:
ls /usr/lib/x86_64-linux-gnu/cmake/
[...] Boost-1.83.0 boost_headers-1.83.0 boost_program_options-1.83.0 [...]
Architecture-independent packages, such as header-only libraries, tend to live under /usr/share/ instead. Eigen is one of these:
ls /usr/share/eigen3/cmake/
Eigen3Config.cmake Eigen3ConfigVersion.cmake Eigen3Targets.cmake UseEigen3.cmake
Both are on CMake's default search path, so find_package locates them without being told where to look. A package installed somewhere else, for instance into /opt or a directory in your home, is found by adding that prefix to CMAKE_PREFIX_PATH, which we return to when we install a library of our own.

Adding the Eigen dependency

Look at Checkpoint 3. A new file src/functionality_eigen.cpp depends on the Eigen library for linear algebra.
Task: Using find_package, modify the CMakeLists.txt in directory src/ to link target cmake_course_lib against Eigen.
Hint: Useful instructions can be found at Using Eigen in CMake Projects.
Note that keyword NO_MODULE is equivalent to CONFIG.

"module" mode for find_package

Libraries don't always come with a CMake config file <PackageName>Config.cmake.
CMake can also find the library based on a file Find<PackageName>.cmake. This behaviour corresponds to using find_package with the keyword MODULE:
find_package(library_name MODULE REQUIRED)
Find<PackageName>.cmake files are cmake language scripts that try to find the library on the system, they are often specific to a particular library and look in specific locations that the library might be found in different operating systems (e.g. /usr/lib, /usr/local/lib).
Such module files are provided by CMake itself for common libraries, they can also be written for a particular use case if required.

Package components

Often libraries are split into different components. E.g. Boost: filesystem, thread, date-time, program-options, numpy...
Most programs only rely on a subset of components, and so it is useful to be able to find and link against only the components that are needed using find_package.
set(boost_components filesystem chrono) find_package(Boost CONFIG REQUIRED COMPONENTS ${boost_components})
The CMake target for a component is <PackageName>::<ComponentName> (e.g. Boost::filesystem).
Boost used to be the classic example of a library found in module mode, but modern Boost (1.70 and later) ships its own BoostConfig.cmake, so we use config mode (CONFIG) here. In fact, CMake's bundled FindBoost module was deprecated in CMake 3.30 (policy CMP0167), so CONFIG is now the recommended way to find Boost. Module mode is still important for the many libraries that only ship a Find<PackageName>.cmake module.

Adding the Boost dependency

Look at Checkpoint 4. The executable exe/main.cpp depends on the Boost Program Options library for handling command line arguments.
Task: Using find_package in CONFIG mode, modify the CMakeLists.txt in directory exe/ to find and link target main_executable against Boost::program_options.