Add cpp files from sub directories in target_sources or not

We are moving from some build system to CMake for a large project.
We have everything working, though we are now cleaning up some stuff.

Currently we have something like:

target_sources(target_o PRIVATE
    very/long/path/to/file.cpp
    path/to/file.cpp
    path/to/file2.cpp
    ...)

Note that this code is currently generated as it is easier to maintain together with the old build system.

Though, on some projects like LLVM, you rather see something like:

add_subdirectory(very)
add_subdirectory(path)

This than recurses through the folder structure and it ends up with:

target_sources(target_o PRIVATE file.cpp file2.cpp)

I see advantages to both approaches, like having 1 place where all sources of a target are known in the first version. The second version makes renaming directories much easier.

Is there a recommended way to detail with many cpp files in a directory structure and adding them to targets? If not, what are the most important arguments for either approach?

My advice is generally to make each CMakeLists.txt responsible for things in the same directory as itself, and delegate things in subdirectories to the CMakeLists.txt files in those subdirectories. Avoid pulling up lists of files from subdirectories to their parents. This has a few advantages:

  • Whenever you’re adding or removing files, you know that the CMakeLists.txt file you need to update is in the same directory as those files. You don’t have to go searching up the parent directory hierarchy to find which CMakeLists.txt file is adding them.
  • It is easier to move directories around if you need to do that at some point, since each directory tends to be relatively self-contained.
  • Each CMakeLists.txt tends to be simpler and more focused.
  • If you need to conditionally add things to the build, this structure tends to facilitate that by allowing you to just conditionally add a subdirectory. This is especially helpful when you have platform-specific subdirectories.
2 Likes