Suppose I have a project myproj with a single executable myproj_exec that depends on code in hundreds of files. Let's choose C++ as a language (although it could be C and perhaps one of any number of compiled languages). Some of the files are more closely related, but they are not used together cohesively enough to be spun off into separate libraries. Suppose also that these files are scattered in a tree of subdirectories.
Now, when building my executable - or perhaps when authoring CMakeLists.txt files for my project - I have (at least) two options for how to define the relations between these source files and the myproj executable:
Adding each of the files directly as dependencies for the executable target, e.g. in each subdir have
# CMakeLists for subdir target_sources(myproj_exec subdir_file_1.cpp subdir_file_2.cpp)Defining intermediate, per-subdirectory library targets, and having the executable depend on these intermediates, e.g.
# CMakeLists for subdir add_library(some_sub_dir_artificial_tgt) target_sources(some_sub_dir_artificial_tgt subdir_file_1.cpp subdir_file_2.cpp) target_link_libraries(myproj_exec some_sub_dir_artificial_tgt)or perhaps the last line isn't included, and in the top-level
CMakeLists.txtwe would have something like:target_link_libraries(myproj_exec dir_lib_1 dir_lib_2 dir_lib_3)
What considerations would you make in choosing between these two approaches?
Notes:
- Assume that there isn't a significant motivation for defining these libraries otherwise than in the context of building
foo. - These artificial target are not intended to be shared libraries, but rather linked statically into the executable.
When talking about gratuitously introducing static libraries: I can't think of a good reason to do this.
For shared libraries: Each shared library is linked on its own. By clever partitioning of the code base into shared libraries, you may be able to significantly reduce load on the linker, with potential benefits for your build times. This requires deliberate engineering effort though and also has potential downsides (in particular a risk of increased startup times for your application).