Using ExternalProject Modules
Let's learn about how to import and use external projects.
We'll cover the following...
Online reference books on CMake will suggest ExternalProject
and FetchContent
modules to deal with the management of dependencies in more complex projects. That's actually good advice, but it's often given without appropriate context. Suddenly, we're facing a lot of questions. What are these modules for? When to choose one over the other? How exactly do they work, and how do they interact with each other? Some answers are harder to find than others, and surprisingly, CMake's documentation doesn't provide a smooth introduction to the subject. Not to worry—we'll take care of it here.
ExternalProject
CMake 3.0.0 introduced a module called ExternalProject
. As you can guess, its purpose was to add support for external projects available in online repositories. Over the years, the module was gradually extended for different needs, resulting in quite a complicated command—ExternalProject_Add()
. And we mean complicated—it accepts over 85 different options. No wonder, as it provides an impressive set of features:
Management of directory structure for an external project
Downloading of sources from a URL (and extracting from archives if needed)
Support for Git, Subversion, Mercurial, and CVS repositories
Fetching updates if needed
Configuring and building the project with CMake, Make, or with a user-specified tool
Performing installations and running tests
Logging to files
Asking for user input from terminals
Depending on other targets
Adding custom commands/steps to the build
The ExternalProject
module populates the dependencies during the build stage. For every external project added with ExternalProject_Add()
, CMake will execute the following steps:
mkdir
: Create a subdirectory for the external project.download
: Get the project files from a repository or URL.update
: Refresh the files on rerun for download methods that support delta updates.patch
: Optionally execute a patch command that alters downloaded files for the needs of the project.configure
: Execute the configure stage for CMake projects or manually specified command for non-CMake dependencies.build
: Perform the build stage for CMake projects, and for other dependencies, execute themake
command.install
: Install CMake projects, and for other dependencies, execute themake
...