log0
log0

Reputation: 10937

Cmake override find_package for a given target

We have a CMakeLists.txt that links (for instance) opencv to our various binaries. This is done as follow:

find_package(OpenCV REQUIRED core imgproc highgui contrib) 
target_link_library(XXX opencv_core)

We also would like to allow the person building the library to provide its own opencv library. It seems that this could be done setting -DCMAKE_PREFIX_PATH to the right path.

cmake -DCMAKE_PREFIX_PATH=".../mybuild/include;.../mybuild/lib" .  

However I would like to be sure the library used is exactly the one specified by the client (i.e. if there is nothing in /mybuild/lib the configuration fails).

How can I allow somebody building the library to override the library used ? (if nothing is specified it should fall back to find_package-s)

Upvotes: 4

Views: 4030

Answers (1)

Tsyvarev
Tsyvarev

Reputation: 66061

In short

  1. If the package provides <package>Config.cmake script, user may specify <package>_DIR CMake variable for locate this script.

    Searching other places in that case may be disabled with NO_DEFAULT_PATH option for find_package().

  2. If a package is searched with Find<package>.cmake script, there is no (generic) way for disable searching other places if user provides hint variable but it is wrong.

Explanations

Firstly, CMAKE_PREFIX_PATH provides additional installation tree for all packages. As this variable is applied to all find_package() calls, it is not wise to require all packages to be found under it.

When talk about the ways for specify installation directory for specific package, we need to distinguish two kinds of "find" scripts:

  1. <package>Config.cmake (or some alternative names, see find_package documentation).

    These scripts are shipped with the packages themselves. And there is universal way for user to specify location of such packages: CMake variable <package>_DIR, which should point to the directory with *Config.cmake script.

    While default behaviour of find_package() is treating <package>_DIR variable as an additional hint, passing NO_DEFAULT_PATH option disables all implicit paths:

    if(<package>_DIR) # Variable is set by the user or by previous `cmake` run.
        # Search only under given directory.
        find_package(<package> NO_DEFAULT_PATH) 
    else()
        # Search everywhere (as documented for 'find_package').
        find_package(<package>) 
    endif()
    
  2. Find<package>.cmake.

    This script either is shipped with CMake or should be shipped with the project.

    Most of such scripts allows to hint about package location with variable (CMake or environment one) like <package>_DIR, <package>_ROOT or so.

    However, almost all such scripts treat hint variable only as additional search place, so if variable is set to wrong value, they simply ignore it. And without modifying the script you cannot change that behavior.

Upvotes: 6

Related Questions