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.