Search code examples
c++dependency-managementbuild-system

Cleanest way for automated dependency management in c++


Related question: C++ Build Systems - What to use?

I am struggling to find a nice build / dependency management tool for my c++ project, with the following desired features:

  • able to specify a dependency by name, version
  • dependencies' "include" directories are automatically included during compilation of my application
  • the dependencies are automatically downloaded, built, and linked to my application
  • transitive dependencies also have the above two behaviours
  • ability to specify test-scope dependencies
  • tests are automatically built and run, potentially with a memory leak check tool (e.g. valgrind)
  • potentially run a coverage tool, e.g. gcov
  • cross platform supported

I have used Maven, with the [nar-maven-plugin], and sometimes the [cmake-maven plugin]. However, this means I have to craft a [pom.xml per dependency]. This method isn't particularly nice, as at times, a [nasty pom.xml] has to be crafted to get things to work. Also, it doesn't support running valgrind (no support built in yet).

I have attempted using CMake as I've seen many projects use it, but I find that a lot of time is spent on "writing a build/dependency management system" instead of "using it". Yes it's true I can write many functions that go:

function(RequireSomeLib artifact)
  # ExternalProject_Add(SomeLib ... etc.)
  # find SomeLib package
  # add include dirs(artifact SomeLib_INCLUDE_DIRS)
  # if SomeLib is not just a header library, also link its built library to the artifact
  # for each of SomeLib's dependencies, do this same "call" (transitive dependencies' libraries must also be linked when building an executable)
endfunction()

for each dependency. Tedious, but currently the cleanest way I see going forward.

With the premise that CMake is used by libraries that my project depends on, is there a better method to solving this problem?

I have not seen or tried SCons, AutoTools, or QMake (yet).

In Java, the "retrieve dependencies, build, test, and publish" issue is much simpler ._.


Solution

  • All build systems for C++ will need you to code in dependencies and package detection. Every one of them has been created out of frustration with previous technologies, with the stated intent to remove the need for boilerplate code, and to create a complete, cross-platform, automated, easy to use solution, but at the end of the day, you will end up writing code besides your code for your package to be built.

    If you look hard enough, you will find debates among advocates of each build system. I found one of such a couple years ago. Their arguments were so weak that I ended up abandoning the search.

    I am a user of CMake for one simple reason: it was the first I could find some years ago that allowed me to spawn different build directories. I'm sure all modern build systems have implemented this idea already, but I stuck with CMake just because I became used to it. Honestly I have found very few sensible advantages over bare bones Makefile. I had to write boilerplate code for my CMakeFiles.txt, even though it was a C++ project without dependencies.

    Some time later I decided to try out some different IDEs; I had the good fortune that Qt Creator runs on CMake projects; there is the other reason I stayed on CMake.

    My advice to you is to visit each build system's webpage; check out their currently implemented features (not TODOs), comparisons to other systems, IDE support, and the complexity of the code you have to write for them. I am pretty sure you will not find a build system satisfying all of the requirements you have, so you will have to test them thoroughly to see which one works best for you.