Creating super projects with CMake's ExternalProject
Some time ago, I wrote a piece about CMake. It was more of a rant, written in the heat of the moment, after being frustrated by some of CMake’s idiosyncrasies. Ironically, it has become one of the most read posts on this blog, which is a bit disappointing. I would like to believe that there are far more interesting and useful posts available here but it is what it is.
My concluding issue in that post was related to dependency management between a set of CMake projects which comprised a “stack”. Recently, having to work with cmake once again, I’ve discovered CMake’s ExternalProject - which mitigates that problem significantly.
Recap
To cut the long story short, CMake identifies three stages:
- project configuration
- build system generation
- project build
In configure stage, it tries to resolve all targets and dependencies but some of these might be provided as a result of the build stage. So, it’s a bit of a catch 22 situation.
As I mentioned, there are many hacks to solve this problem.
ExternalProject
might be classified as one as well however, it feels like a
clean solution to the problem.
Problem definition
Consider the following example project structure.
|
|
The dependecies would be:
The global CMakeLists.txt
would contain:
|
|
ExternalProject
is executed and installed during the configure stage. So,
from the perspective of the global, super project build, there are no targets
to produce. That’s all right though. All the magic happens within the build
system for each individual subproject.
I won’t quote or discuss any of the individual subproject’s CMakeLists.txt
as
they are quite verbose. For reference, I’m providing a repo with the
discussed project layout.