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