tjwrona
tjwrona

Reputation: 9035

CMake "find_package" command on a package that was not installed is unexpectedly successful

I am following chapter-02/recipe-06 in "CMake Cookbook". This particular example requires the Eigen C++ libraries.

I attempted to build the example and got the error that Eigen was not found.

CMake Error at CMakeLists.txt:9 (find_package):
  Could not find a package configuration file provided by "Eigen3" (requested
  version 3.3) with any of the following names:

    Eigen3Config.cmake
    eigen3-config.cmake

  Add the installation prefix of "Eigen3" to CMAKE_PREFIX_PATH or set
  "Eigen3_DIR" to a directory containing one of the above files.  If "Eigen3"
  provides a separate development package or SDK, be sure it has been
  installed.

This was expected because the library was not installed on my system.

I then downloaded the ".zip" file for the Eigen libraries and unzipped it to an arbitrary location outside of my project. I created a "build" folder in the Eigen directory and ran cmake .. in the "build" folder. (I only ran cmake - I did NOT build or install the package.)


After running CMake on the Eigen build directory, I went back to the example code for "recipe-06" and it was magically able to find the Eigen library and built successfully even though Eigen was never built or installed.

Somehow just running CMake in the Eigen project made CMake aware of the Eigen libraries location. After doing this, any projects that do find_package to find Eigen3 somehow get the ${Eigen3_DIR} variable defined and are able to find it.


Looking at the CMake documentation for find_package I don't see any explanation of why this works. Eigen is not in any of the typical locations that find_package searches. According to the documentation it looks like it should NOT be found.

Even more interesting - it doesn't matter where I put Eigen on my system. I can put it literally anywhere and it will still find it.

According to everything I see in the documentation it should not be found... but it is found. So the question is how? Why does this work?

Additional info: I am using CMake version 3.13.3

Upvotes: 3

Views: 3637

Answers (1)

Tsyvarev
Tsyvarev

Reputation: 66061

There are 2 "origins" of XXXConfig.cmake files, used internally by find_package() call.

Usually, XXXConfig.cmake file is produced when the project is installed, and the file contains information about installed libraries and headers.

But CMake provides also an export() command, which allows to export build tree.

export(PACKAGE <name>)

Store the current build directory in the CMake user package registry for package <name>. The find_package command may consider the directory while searching for package <name>.

Eigen's CMakeLists.txt uses export() command, so the project becomes detectable with find_package just after running cmake for Eigen.

Upvotes: 3

Related Questions