Dallas Zimmer
Dallas Zimmer

Reputation: 71

Where should find_package be called in CMakeLists.txt?

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?

  1. In the CMakeLists.txt file for each executable/library that needs them?
  2. Or, once in a top-level 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

Answers (2)

John McFarlane
John McFarlane

Reputation: 6107

Invoke find_package in the CMakeFiles.txt file in which the package is referenced. References might include

Following similar principles such as Include What You Use and Keep scopes small, you should aim to ensure that software items are:

  • Cohesive: the package is used in that CMakeLists.txt file, so finding the package belongs there too. This brings modularity and makes it easier to relocate or reuse the file, and to see more easily what packages it uses.
  • Uncoupled: distant CMakeLists.txt files don't depend on one another in ways which might be surprising or puzzling. This makes it easier to change one CMakeLists.txt without breaking functionality in another.

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

lubgr
lubgr

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

Related Questions