Replace add_subdirectory with find_package

I have an environment where multiple products on multiple platforms build using a variety of libraries.

Historically, we have assembled CMake projects with liberal use of add_subdirectory. I’d prefer to use something based on find_package instead.

  • Avoid using different APIs for adding modules depending on whether we are developing using entire tree or using a package manager (e.g. Conan)
  • Avoid assumptions about where and how a particular library target is implemented

Is it possible to set things up so find_package will work both for modules in the dev tree and installed / packaged modules?

Sounds like you want to use FetchContent. Check out the FIND_PACKAGE_ARGS option for FetchContent_Declare(). That option is supported with CMake 3.24 or later.

You can make use of the fact that find_package is just an include with superpowers. Here is an example that uses find_package in the code, but fetches the dependency using FetchContent. This is an opt-in mechanism and developers can just set CMAKE_MODULE_PATH to get it.

Module mode

In this mode, CMake searches for a file called Find<PackageName>.cmake, looking first in the locations listed in the CMAKE_MODULE_PATH

When the basic signature is used, the command searches in Module mode first.

You will have to make sure that the build and install interfaces of the dependency match, e.g. if there is no namespaced ALIAS target in the dependency’s build interface that matches the exported target name from the install interface, then you will have to bridge the gap to make the integration transparent in your own project’s code.

1 Like