cmakecmake-modules

Excluding cmake's own distribution modules with `find_package()`


Cmake includes various distribution modules (i.e., populated inside the Modules/ directory of a cmake installation; e.g., /usr/share/cmake-3.5/Modules/FindBoost.cmake).

This creates challenges when developing code that includes internal libraries with names that conflict with these distribution modules, as find_package(Xyz) finds the distribution module (/usr/share/cmake-3.5/Modules/FindXyz.cmake) rather than the user module (/home/user/opt/lib/cmake/Xyz-config.cmake). I've tried setting CMAKE_FIND_ROOT_PATH and CMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY, but to no avail.

How can I force cmake to exclude its own distribution modules when evaluating find_package()?


Solution

  • As an author of the project you may find "legacy" find script (FindXXX.cmake) as non-suitable for you and prefer to use "modern" config script (XXXConfig.cmake or config-xxx.cmake) instead. In that case you may pass additional CONFIG or NO_MODULE option to the find_package:

    find_package(Boost NO_MODULE)
    

    This would prevent CMake from searching FindBoost.cmake script and forces it to search BoostConfig.cmake (or config-boost.cmake).

    If config script could not be found with NO_MODULE or CONFIG option, then CMake will report an error even if corresponding find script exists.

    Alternatively, you may set CMAKE_FIND_PACKAGE_PREFER_CONFIG variable:

    set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
    

    so CMake would check config script first. But if this script is missing, then CMake will try to use find script.


    As the user of the project you may find the config script for some package nicer than the find one... but it is better to change nothing in this case: It could be that project you are using can work only with the find script, and cannot work with config one. (E.g. the project uses variables, which are created by find script to refer the libraries, but config scripts usually create IMPORTED targets).