10
votes

Assume I have written a library <mylib> that I can build an install via cmake. And I also have a <mylib>Config.cmake file that can locate all necessary files (library, headers, ...) and exports a target for the library.

If I want to use the library with find_package(...), cmake needs to know the location of the config file. I know that I could pass this every time I build a project using the library or I could (for cmake 3.13 and newer) point the <mylib>_ROOT environment variable to it.

But there is a solution for this that seems much simpler to me: I can register a package in the cmake package registry with the export(PACKAGE <PackageName>) command. But if I understand its documentation correctly this only allows to register the build directory. My build directories typically contain neither the config file, nor other stuff like include files that might be needed. Sure, I could copy them there, but why would I do this if I already have everything nicely set up in the install directory.

Therefore my questions:

  • What is the reason that only registering of the build directory is supported by export(PACKAGE ...)?
  • Is there any way to register my install directory in the cmake package registry?
1

1 Answers

0
votes

The use of the CMake package registry is discouraged because it is liable to change the behavior of other builds on the system. From the latest documentation (emphasis mine):

Changed in version 3.15: By default the export(PACKAGE) command does nothing (see policy CMP0090) because populating the user package registry has effects outside the source and build trees. Set the CMAKE_EXPORT_PACKAGE_REGISTRY variable to add build directories to the CMake user package registry.

To the extent that this question is an XY problem, a better workflow is simply to pick a common install prefix, say /path/to/prefix, and then point every build that needs the packages in there to it via -DCMAKE_PREFIX_PATH=/path/to/prefix. Build each project in dependency order and then cmake --install /path/to/build --prefix /path/to/prefix before moving on to the next.

This relieves you from setting _ROOT variables for each of your dependencies, because you have installed them all to the same prefix. CMAKE_PREFIX_PATH is also one of the few environment variables that CMake reads to initialize the corresponding CMake variable, so you can set it in your shell to avoid typing -D... manually. To avoid affecting other projects on your system, something like direnv might be useful to manage setting and unsetting CMAKE_PREFIX_PATH.