Debug vcpkg portfiles in CMake script mode with Visual Studio Code

Ben McMorran

We recently announced support for debugging the CMake language using the VS Code CMake Tools extension. Now in version 1.16 of the extension, you can fine-tune the debugger configuration using a launch.json file. This enables debugging in CMake script mode in addition to the existing debugging of CMake project generation. 

CMake script mode is an alternative way of running CMake that does not generate a build system, but instead uses the CMake language as a general-purpose scripting language. While script mode is not widely used (although there are fun esoteric examples), it is the mechanism that powers vcpkg portfiles. vcpkg uses portfiles to know how to acquire, build, and install libraries. Through a combination of the new experimental “–x-cmake-debug” vcpkg option and CMake Tools, it’s now possible to debug these portfiles in VS Code. This is helpful when adding a library to the vcpkg catalog. 

Debugging vcpkg portfiles

As an example, we’ll explore how to debug the vcpkg portfile for zlib. First, ensure you have CMake Tools 1.16 and CMake 3.27 installed. Next, clone the vcpkg repo and open it in VS Code. 

> git clone https://github.com/microsoft/vcpkg
> cd vcpkg
> .\bootstrap-vcpkg.bat (or bootstrap-vcpkg.sh on Linux)
> code .

We’ll use a tasks.json to define a task that installs the zlib library with the --x-cmake-debug option and a launch.json file to configure CMake Tools to attach to the zlib portfile as it’s being run. In VS Code, create a new “.vscode” directory. Add the following tasks.json and launch.json files to this directory.

tasks.json

{ 

    "version": "2.0.0", 

    "tasks": [ 

        { 

            "label": "Reinstall zlib", 

            "type": "shell", 

            "isBackground": true, 

            "command": "& \"${workspaceFolder}/vcpkg.exe\" remove zlib; & \"${workspaceFolder}/vcpkg.exe\" install zlib --no-binarycaching --x-cmake-debug \\\\.\\pipe\\portfile_debugging", 

            "problemMatcher": [ 

                { 

                    "pattern": [ 

                        { 

                            "regexp": "", 

                            "file": 1, 

                            "location": 2, 

                            "message": 3 

                        } 

                    ], 

                    "background": { 

                        "activeOnStart": true, 

                        "beginsPattern": ".", 

                        "endsPattern": "Waiting for debugger client to connect" 

                    } 

                } 

            ] 

        } 

    ] 

} 

The important parts of the configuration are the command, which removes zlib if it’s already installed and then reinstalls it, and the endsPattern, which tells VS Code when it can consider the task complete. CMake will output the “Waiting for debugger client to connect” string as soon as it has finished initializing the debugger. The rest of the problemMatcher values are required to satisfy VS Code’s launch configuration schema but are not used in this example. 

launch.json

{ 

    "version": "0.2.0", 

    "configurations": [ 

        { 

            "type": "cmake", 

            "request": "launch", 

            "name": "Debug zlib portfile", 

            "cmakeDebugType": "external", 

            "pipeName": "\\\\.\\pipe\\portfile_debugging", 

            "preLaunchTask": "Reinstall zlib" 

        } 

    ] 

} 

This CMake Debugging configuration uses a cmakeDebugType of external, meaning the CMake Tools extension is not responsible for launching CMake (in this case vcpkg is launching CMake). Notice how we use the same pipe name as the vcpkg install task.

Finally, open ports/zlib/portfile.cmake and set a breakpoint on line 2 (the call to vcpkg_from_github). In the VS Code Run and Debug view, select the Debug zlib portfile configuration and click the play button to start debugging. VS Code will automatically run the vcpkg install task until the debugger is ready for client connections, then start a debugging session. At this point it’s possible to step through the portfile and inspect variables. 

Debugging your portfile.cmake using the CMake debugger

Debugging in CMake script mode without a configuration

It’s also possible to quickly debug CMake scripts without a launch.json configuration. This can be a handy way to experiment with CMake commands. To try it, create a new file named “debugging_example.cmake” in VS Code, open it in the editor, and add this content: 

debugging_example.cmake

set(WORLD "World!") 

message(STATUS "Hello ${WORLD}") 

Set a breakpoint on line 1 of this file. In the Run and Debug view, select the CMake Debugger…” option from the debug configuration dropdown and choose CMake: CMake Script” from the quick pick menu. Click the play button and the script will start running under the debugger, with no launch.json configuration needed!

Debugging a CMake script with the CMake debugger without a launch.json

What’s next?

CMake script mode debugging currently only works in VS Code, but we are planning to bring the same functionality to Visual Studio in a future release. Learn more about all the options for debugging CMake scripts in our documentation. 

Send us your feedback!

We hope this helps your CMake workflows in VS Code. Download the CMake Tools extension for Visual Studio Code and let us know what you think. We would love to see what you contribute to our repo and are active on reviews and collaboration. If you have any issues, please file an issue to our repo here. Comment below or reach us via email at visualcpp@microsoft.com or via Twitter at @VisualC. 

0 comments

Discussion is closed.

Feedback usabilla icon