CMake Debugging Guide ********************* This guide explains how to attach a debugger to CMake's unit testing framework. We'll focus on using **GDB** on Linux for both command-line and IDE debugging. See documentation on `CMake Development`_ for more information. .. _`CMake Development`: README.rst Linux: Using GDB ================ On Linux, the GNU Debugger (**GDB**) is the standard tool for debugging the CMake test suite. The core process involves launching the ``cmake`` executable from within GDB with a specific set of arguments that configure and run the desired test. GDB Configuration ----------------- For effective debugging, GDB must be configured to handle child processes correctly, which CMake tests often create. A good practice is to use a local ``.gdbinit`` file in your build directory. This keeps CMake-specific settings separate from your global configuration. **1. Enable Local .gdbinit Files (One-Time Setup)** To allow GDB to automatically load configuration from your build directory, add the following line to your global GDB initialization file at ``$HOME/.gdbinit``. This is a one-time setup that makes future projects easier to manage. .. code-block:: text set auto-load local-gdbinit on **2. Create a Project-Specific .gdbinit** Next, create a ``.gdbinit`` file inside your CMake **build directory**. This file will contain settings specific to debugging CMake. To make this easier, you can symlink the template file provided in the CMake source tree: .. code-block:: bash # Navigate to your build directory cd /path/to/your/cmake/build # Create a symlink to the template ln -s $cmake_srcdir/Utilities/gdb/gdbinit-template .gdbinit The template contains the essential settings for debugging CMake tests: .. code-block:: gdb # Allows GDB to follow child processes set follow-fork-mode child # Allows the parent process continue in parallel set non-stop on Debugging from the Command Line ------------------------------- To start debugging, first cd to the build directory. Then, launch the ``cmake`` executable using ``gdb --args``, which passes the necessary test configuration arguments directly to CMake. .. note:: To get the launch command, run ``ctest -R "RunCMake.$TESTNAME" -VV -N`` The following example runs the ``InstallPackageInfo`` test. .. code-block:: bash # Define paths to your CMake source and build directories CMAKE_SOURCE_DIR="$HOME/cmake" CMAKE_BUILD_DIR="$CMAKE_SOURCE_DIR/build" # Define the specific test to run TEST_NAME="InstallPackageInfo" # Navigate to the build directory cd "$CMAKE_BUILD_DIR" # Launch GDB with the appropriate arguments for the test gdb --args ./bin/cmake \ "-DCMAKE_MODULE_PATH=$CMAKE_SOURCE_DIR/Tests/RunCMake" \ "-DRunCMake_GENERATOR=Ninja" \ "-DRunCMake_SOURCE_DIR=$CMAKE_SOURCE_DIR/Tests/RunCMake/$TEST_NAME" \ "-DRunCMake_BINARY_DIR=$CMAKE_BUILD_DIR/Tests/RunCMake/$TEST_NAME" \ "-P" "$CMAKE_SOURCE_DIR/Tests/RunCMake/RunCMakeTest.cmake" Once GDB loads, you may set breakpoints (e.g., ``b cmInstallCommand``) and then start the test by typing ``run``. Filtering Tests --------------- Some test suites contain multiple sub-tests. To run only a specific one, you can use the ``RunCMake_TEST_FILTER`` environment variable. For example, to run only the "Metadata" test within the ``InstallPackageInfo`` suite, you can set the variable before launching GDB: .. code-block:: bash RunCMake_TEST_FILTER="Metadata" gdb --args ... Alternatively, you can set the environment variable from within the GDB session before running the test: .. code-block:: gdb-prompt (gdb) set environment RunCMake_TEST_FILTER Metadata (gdb) run IDE Integration --------------- You can also debug CMake tests directly from your IDE. CLion ===== If you have configured GDB to auto-load local ``.gdbinit`` files as described above, CLion will automatically pick up the necessary settings. A simple way to debug a test is to modify its ``CTest`` run configuration: #. **Select the Test**: In the "Run/Debug Configurations" dialog, find the ``CTest`` entry for your test (e.g., ``RunCMake.InstallPackageInfo``). #. **Add CTest Arguments**: In the "CTest arguments" field, add ``--extra-verbose``. This is helpful for debugging because it prints the exact command ``CTest`` uses to run the test. #. **Set Working Directory**: Ensure the "Working Directory" field is set to ``$CMakeCurrentLocalGenerationDir$``. You can now set breakpoints in your code and debug this configuration. Visual Studio Code ================== Create a ``launch.json`` file in the ``.vscode`` directory of your CMake **source folder** with the following configuration. This configuration hardcodes the necessary GDB settings, so it does not depend on an external ``.gdbinit`` file. .. code-block:: json { "version": "0.2.0", "configurations": [ { "name": "Debug CMake Test", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/bin/cmake", "args": [ "-DCMAKE_MODULE_PATH=${workspaceFolder}/Tests/RunCMake", "-DRunCMake_GENERATOR=Ninja", "-DRunCMake_SOURCE_DIR=${workspaceFolder}/Tests/RunCMake/InstallPackageInfo", "-DRunCMake_BINARY_DIR=${workspaceFolder}/build/Tests/RunCMake/InstallPackageInfo", "-P", "${workspaceFolder}/Tests/RunCMake/RunCMakeTest.cmake" ], "stopAtEntry": false, "cwd": "${workspaceFolder}/build", "environment": [], "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "Follow child processes", "text": "set follow-fork-mode child", "ignoreFailures": true }, { "description": "Don't stop the parent process", "text": "set non-stop on", "ignoreFailures": true } ] } ] } .. note:: Remember to change the test name (``InstallPackageInfo``) in the ``"args"`` section to the specific test you want to debug.