|
@@ -0,0 +1,197 @@
|
|
|
+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.
|