Reputation: 71
Including external libraries in a cmake project is usually performed using find_package()
.
But in a large multi-application / multi-library project, it is typical for some 3rd-party and/or system libraries to be used by multiple applications and libraries.
Where should find_package()
for these common libraries be called?
CMakeLists.txt
file for each executable/library that needs them?CMakeLists.txt
file?The first options seems to be a more modular approach, but the associated find_package()
scripts are executed for each library/executable that uses them. This can slow down the configuration step.
The second option is more efficient, but looks a bit too much like a global variable to me.
Upvotes: 7
Views: 2259
Reputation: 6107
Invoke find_package
in the CMakeFiles.txt file in which the package is referenced. References might include
target_link_libraries
.Following similar principles such as Include What You Use and Keep scopes small, you should aim to ensure that software items are:
Note that while this approach is more robust, scalable and maintainable, it's at least as verbose and onerous to follow. If you prefer to list packages in the root CMakeLists.txt instead, then at least be consistent and find them all there together.
Upvotes: 0
Reputation: 38315
I would distinguish between subprojects/-directories that might be standalone packages on their own (or already are) and those that exclusively reflect the source code structure.
In the first case, find_package
should clearly be in the subdirectory CMakeLists.txt
to allow for extracting the subdirectory for a standalone build or distribution. Inefficiency of the configuration step should not be a concern here, as the configuration of a build is not performed that often.
In the second case, I would prefer find_package
calls in the toplevel CMakeLists.txt
. If you don't use the variables set by these calls to populate global variables but use target_link_libraries
instead (as suggested in the comments), this should be clean enough. Sometimes though, found packages do not export proper targets to link against, but rather define some include path variables and the like. Then, it should be easy to define your own INTERFACE
library that encapsulate these flags/paths as usage requirements and propagate them transitively when linked via target_link_libraries
again.
Upvotes: 2