Like it happens to many, our C++ project grew larger and larger, and it finally hit the point where maintainability starts to be a concern, mostly due to build times: even by using
ccache, every change requires anywhere from 30 seconds to 5 minutes to rebuild and test (actually it seems that "linking" is the time-consuming phase, but we are still investigating).
The project consists mainly of a big scientific library, along with some applications which make use of it. For example, there are applications to augment simulation models, or language bindings (python) for integration into other software packages.
Now, it would seem natural to split the library into smaller libraries: the code is already organized in "modules", so this would not be an issue. The problem is with dependency management: we can think of the whole project as a big DAG, where each node is a library module, or external library (due of the project nature, there are many external dependencies on other scientific libraries).
So ideally, when working on a module, we would like to rebuild only that module, plus maybe the related test app, and link it with its dependencies. This would speed up the development cycle considerably.
Consequently, the idea is to handle each "module" as an independent project, that will be separately built into a (static) library. I have two concerns with this approach:
- Imagine that I am working on app A that depends on library B, which itself depends on library C. During development, I find that I need a new feature in library C, so I go ahead and code that. I now have to manually rebuild library C, then library B and finally library A before continuing with the development. When the dependency chain grows larger, this can be problematic.
- If the dependencies of one module change, how to manage the impact on the whole DAG (other modules that change as a consequence)?
I have been researching into several tools that might assist with my scenario. Git submodules is one option, but it does not address my concerns above. Apache Ivy seems not suitable for what I am trying to achieve. I suspect that the answer involves some powerful build system (we are using qmake), so I looked into cmake (but I found its scripting language limited and hard to learn), and then buck and pants.
I am still unsure if this is the way to go, so I would be grateful if someone could share advice and/or experiences.