Search code examples
cmake

How to execute CMake's default find module from my own find module with the same name?


For some reason I want to extend a find module (FindThreads in my case) to do some specific stuff if CMake's FindThreads fails. For the ordinary developer of other parts of our software system this should happen transparently, such that s/he could call find_package(Threads) as usual, so I don't want to give my own find module an exclusive name.

My idea is to add my own FindThreads.cmake in a folder contained in the CMAKE_MODULE_PATH. Because CMAKE_MODULE_PATH has priority find_package(Threads) will execute my own FindThreads.cmake.

But, inside my own FindThreads.cmake I need to execute find_package(Threads ...) such that it executes CMake's original FindThreads.cmake. How to do that?

If that fails my own FindThreads.cmake should try to add a specific Threads lib.

Unfortunately, there is no option NO_CMAKE_MODULE_PATH for find_package to fall back to CMake's own find modules and it seems not to be possible to pass a search path (for example ${CMAKE_ROOT}/Modules) to find_package to override CMAKE_MODULE_PATH.

Versions

  • CMake 3.5 on Linux (Ubuntu 16.04)
  • CMake 3.14 on Windows

Solution

  • You may set CMAKE_MODULE_PATH before find_package call and restore the variable after the call:

    # Save old value of CMAKE_MODULE_PATH.
    set(CMAKE_MODULE_PATH_OLD ${CMAKE_MODULE_PATH})
    # Temporary replace CMAKE_MODULE_PATH
    set(CMAKE_MODULE_PATH "${CMAKE_ROOT}/Modules")
    # Call find_package() with specific CMAKE_MODULE_PATH set.
    find_package(Threads ...)
    # Restore CMAKE_MODULE_PATH
    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH_OLD})
    

    Note, that FindXXX.cmake is executed in the same scope as the caller code, so restoring CMAKE_MODULE_PATH variable is needed even if your script no longer calls find_package but simply returns.

    Also, it is better to use some unique variable's name instead of CMAKE_MODULE_PATH_OLD: it is possible that caller already uses that variable for its own purposes. E.g. you may add some suffix to the variable's name which related to your organization or is unlikely to be used by others.