I'm working on a C++ codebase targeted at multiple platforms, and we've just moved over to CMake as our buildsystem.
Previously our buildsystem was a pretty ad-hoc affair; getting our code under a single common buildsystem has been a real step forward.
The next pain point I've encountered, though, is that I'd like to be able to build our project at a variety of scopes. For example:
- Sometimes I want to build a particular module, plus its tests. Or a suite of modules, plus their tests.
- Sometimes I want to build one of our production packages (which will have build products organized in an entirely different way than for testing during development).
- Sometimes I want to build the whooole codebase, including secondary tools and utilities.
...and of course, I'd rather avoid building absolutely everything as a "default" option that's hard to change. But this precisely seems to be CMake's default option - everything in the source tree is included, unless you specify individual targets by name.
Two options that seem promising, but I feel unsatisfied with, are:
1. Use CMake's INSTALL
and COMPONENT
features. This seems to give me what I want - different installation configurations for the same codebase. However,
- As far as I can tell,
INSTALL
depends on all other targets, so for most configurations I'd be building lots of products I don't need. COMPONENT
is a parameter to CMake itself; I'd need entirely independent build directories in order to build different install components. If I switch from one component to the other, I need to rebuild everything.
2. Create custom targets representing my different scopes/components, describing what targets each "component" depends on.
- This seems to involve giving up on
INSTALL
functionality entirely. And if any of my use-cases needs the build products set up in any particular layout, or anything elseINSTALL
-like (most of them do), I'd need to recreate that functionality manually as part of each of these custom targets. This seems awfully cumbersome.
Is there a better way to define different "types" of builds? (Or, am I missing a better way of handling this?)