Debug Packages and Programs Finding using CMake

Debug Packages and Programs Finding using CMake

When CMake tries to locate external programs, libraries, or headers, it runs through a detailed search process that can involve system paths, environment variables, CMake cache entries, and custom search directories. Most of the time this works silently, but when something goes wrong, it can be frustrating to figure out what's happening under the hood. This tutorial explains how to debug packages and programs finding using CMake.

We'll start with a small CMakeLists.txt example that tries to find Git:

cmake_minimum_required(VERSION 3.27)
project(myapp)

set(CMAKE_CXX_STANDARD 17)

find_package(Git)

add_executable(${PROJECT_NAME} main.cpp)

If you just want to see how CMake is trying to find a specific package (e.g. Git), we can use the --debug-find-pkg option:

cmake -S . -B build --debug-find-pkg=Git

This produces detailed logs from the FindGit.cmake module, including every search directory and the final location where Git was found. Truncated output:

CMake Debug Log at /usr/share/cmake-4.1/Modules/FindGit.cmake:86 (find_program):
  find_program called with the following settings:

    VAR: GIT_EXECUTABLE
    NAMES: "git"
    Documentation: Git command line client
    Framework
      Only Search Frameworks: 0
      Search Frameworks Last: 0
      Search Frameworks First: 0
    AppBundle
      Only Search AppBundle: 0
      Search AppBundle Last: 0
      Search AppBundle First: 0
    CMAKE_FIND_USE_CMAKE_PATH: 1
    CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1
    CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1
    CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1
    CMAKE_FIND_USE_INSTALL_PREFIX: 1

  find_program considered the following locations:

    /usr/local/sbin/git
    /usr/local/bin/git
    /usr/sbin/git

  The item was found at

    /usr/bin/git

Sometimes the problem isn't that CMake can't find a package - it's that it's finding the wrong version of a program. For example, if your system has multiple make binaries, you might see unexpected build behavior. CMake stores the path it found in variables like CMAKE_MAKE_PROGRAM, CMAKE_C_COMPILER, CMAKE_CXX_COMPILER, etc. To understand why a specific variable got its value, we can use --debug-find-var option:

cmake -S . -B build --debug-find-var=CMAKE_MAKE_PROGRAM

Truncated output:

CMake Debug Log at /usr/share/cmake-4.1/Modules/CMakeUnixFindMake.cmake:5 (find_program):
  find_program called with the following settings:

    VAR: CMAKE_MAKE_PROGRAM
    NAMES: "gmake"
           "make"
           "smake"
    Documentation: Path to a program.
    Framework
      Only Search Frameworks: 0
      Search Frameworks Last: 0
      Search Frameworks First: 0
    AppBundle
      Only Search AppBundle: 0
      Search AppBundle Last: 0
      Search AppBundle First: 0
    CMAKE_FIND_USE_CMAKE_PATH: 1
    CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1
    CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1
    CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1
    CMAKE_FIND_USE_INSTALL_PREFIX: 1

  find_program considered the following locations:

    /usr/local/sbin/gmake
    /usr/local/bin/gmake
    /usr/sbin/gmake

  The item was found at

    /usr/bin/gmake

If you want to see how CMake searches for everything - all packages, programs, and more - use the --debug-find option without any arguments:

cmake -S . -B build --debug-find

This will produce a detailed log of every search CMake performs during the configuration step.

Leave a Comment

Cancel reply

Your email address will not be published.