Karnivaurus
Karnivaurus

Reputation: 24121

Where does cmake look to find packages?

In Ubuntu 14.04, I am compiling a C++ program, which depends on the following packages: CUDA and OpenNI. In the CMakeListst.txt file for this program, there is the following:

find_package(CUDA)
find_package(OpenNI)

And the output to cmake is:

Found CUDA: /usr/local/cuda (found version "6.5") 
-- Could NOT find OpenNI (missing:  OpenNI_LIBRARY OpenNI_INCLUDE_DIR)

So, it seems that CUDA was found, but OpenNI was not. Now, I have definitely installed OpenNI, but perhaps not in the standard location. Whereas the CUDA files are in usr/local/cuda as stated, my OpenNI files are in ~/Libraries/OpenNI.

My question is: How do I tell cmake where to look for to define the OpenNI_LIBRARY and OpenNI_INCLUDE_DIR variables? Is there a file somewhere which cmake has paths defined for all these variables, which I might need to manually edit?

Upvotes: 13

Views: 13576

Answers (3)

user2169513
user2169513

Reputation: 222

Even if this is a quite old question: If you call cmake with --debug-find it will tell you where it looks for a package that you requested through a find_package() call in your CMake script.

My personal preference, especially for packages residing in their very own dedicated location, is to define an environment variable <package_name>_DIR, which points to the package's configuration file (assuming that the lib provides one). See the find_package() documentation about the search procedure for more details.

Upvotes: 5

ComicSansMS
ComicSansMS

Reputation: 54589

There is no unified way that tells you where a find script will attempt to look for a library.

This is a bit unfortunate, but the only way to know for sure is to check the source of the find script itself. Most find scripts rely on find_library and similar commands to locate their files, which will by default search in a number of locations that are obvious candidates (like /usr/local/ on Unixes).

Unfortunately, this alone does not get you very far. If you are stuck on a platform like Windows where there is no reasonable default location, or you want to avoid polluting the directory tree, you need another way. Most find scripts therefore allow injecting the location of the library in some way.

In my experience, the cleanest way to do this is through environment variables. They are flexible to configure and convenient to use. In particular, you can make them persistent by adding them to your user's environment, so you don't have to type them out each time you run CMake.

If you check for example the find script for CUDA that ships with CMake, you will notice that it uses the environment variables CUDA_PATH, CUDA_LIB_PATH, CUDA_INC_PATH and CUDA_BIN_PATH (along with a few others) for this purpose.

An alternative is to directly set the result variables of the find script in the cache from the command line via CMake's -D parameter.

In any case you will have to check the find script source to find out what is the best course of action.

A word of advice: Do not attempt to hardcode locations in your own CMakeLists. While this might seem like a quick solution, it's also a very dirty one that essentially makes your build system non-relocatable. Always reach for solutions that allow the user to configure the build system from the outside without having to change CMake code.

Upvotes: 4

Jens Munk
Jens Munk

Reputation: 4725

It looks in CMAKE_MODULE_PATH.

Append to this path using expressions like this

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

Upvotes: 5

Related Questions