CMake Launch durch VSCode

Das CMake Plugin in Visual Studio Code ist echt genial zum Bauen der Sourcen.
Aber die Ausführung im Debugger kommt nicht ohne Konfiguration und ein paar Sonderfälle aus.


Eigentlich lag meine zögerliche Migration von Visual Studio zu VSCode nur an einer Sache: die fehlende CMake-Integration.
Folglich ist dessen Setup vermutlich der wichtigste Schritt in einem modernen Projekt.

Visual Studio Solutions haben den Vorteil, dass sie einem ein vollständiges Debugging-Environment zur Verfügung stellen.
Ich schreibe Code, setzte per Maus einen Breakpoint, drücke F5 und beobachte den Programmablauf.
Braucht ein Programm Kommandozeilenparameter, werden die in den Projekteigenschaften einfach angegeben, dann F5 und alles läuft.

VSCode kennt nur Quelldateien, die es editieren kann. Alles andere muss von Plugins übernommen und über JSON Dateien konfiguriert werden.

CMake Targets starten

Hat man Microsoft’s CMake-Plugin installiert lässt einem der CMake-Tab im Menü folgendes einstellen:

  • Configure
    • Auswahl der Build-Tools (also MSVC x64, oder GCC ARM64)
    • Auswahl für Debug oder Release Builds
    • Starten des CMake-Configure Schrittes zum Erzeugen aller notwendigen Build-Scripts
  • Build
    • Auswahl entweder eines bestimmten CMake-Targets zum Bauen oder Auswahl von “allen” Targets.
    • Starten das Bauens des Projektes für das ausgewählte Target oder alle Targets
  • Debug
    • Auswahl eines Targets, das im Debugger gestartet werden soll
    • Start einer Debug-Sitzung.

Nur leider braucht man für das Debuggen immer eine Konfiguration, und die muss vorher erst mal angelegt werden. Wir brauchen für jeden unterstützten Debugger einen Launch Eintrag.

CMake Debug Launch in VSCode

Ein Code sagt mehr als tausend Worte.

Meine .vscode/launch.json Datei sieht in etwas so aus:

 1// .vscode/launch.json
 2{
 3  "version": "0.2.0",
 4  "configurations": [
 5    {
 6      "name": "(gdb) CMake Launch",
 7      "type": "cppdbg",
 8      "request": "launch",
 9      "program": "${command:cmake.launchTargetPath}",
10      "args": [],
11      "cwd": "${workspaceFolder}",
12      "MIMode": "gdb",
13      "setupCommands": [
14        {
15          "description": "Enable pretty-printing for gdb",
16          "text": "-enable-pretty-printing",
17          "ignoreFailures": true
18        }
19      ]
20    },
21    {
22      "name": "(msvc) CMake Launch",
23      "type": "cppvsdbg",
24      "request": "launch",
25      "program": "${command:cmake.launchTargetPath}",
26      "args": [],
27      "cwd": "${workspaceFolder}"
28    }
29  ]
30}

Da ich ja immer zwischen Windows und Linux hin- und her wechsle, sind ein MSVC und GCC Debug-Launcher konfiguriert.

Die magische Zeile lautet auf:
"program": "${command:cmake.launchTargetPath}"
Denn die sorgt dafür, dass in einer Debug-Sitzug genau das Programm gestartet wird, das mit dem aktuell unter Debug eingetragenen CMake Target eingestellt ist.

Da MSVC und GDB unterschiedliche Plugins nutzen, sind auch die Konfigurationen verschieden aber großteils selbsterklärend.

Im Feld args lässt uns Kommandozeilenparameter für das zu startende Programm angeben, allerdings gibt es eben nur diesen einen Eintrag. In Visual Studio könnte man für jedes Projekt eigene Werte eintragen, hier können wir aber nur “den nächsten Lauf” konfigurieren.

Beim Starten der Debug-Sitzung erscheint ein Popup, welches einem immer die beiden Launcher zur Auswahl stellt. Man muss eben selbst wissen, ob man unter MSVC/WinDebug oder GCC/GDB debug-t.

CTest

Noch komplizierter wird das ganze bei CTest. Hat man nämlich Tests definiert, kann man diese im Test-Fenster auch mit einer Debug-Session starten.

Hier braucht man wieder zwei weitere Launcher:

 1{
 2  "version": "0.2.0",
 3  "configurations": [
 4  /// CMake Launch entries from above
 5    {
 6      "name": "(gdb) CTest Launch",
 7      "type": "cppdbg",
 8      "request": "launch",
 9      "cwd": "${cmake.testWorkingDirectory}",
10      "program": "${cmake.testProgram}",
11      "args": [ "${cmake.testArgs}"],
12    },
13    {
14      "name": "(msvc) CTest Launch",
15      "type": "cppvsdbg",
16      "request": "launch",
17      "cwd": "${cmake.testWorkingDirectory}",
18      "program": "${cmake.testProgram}",
19      "args": [ "${cmake.testArgs}"],
20    }
21  ]
22}

Die Token cmake.testProgram und cmake.testArgs sorgen dafür, dass das Testprogramm genau so gestartet wird, wie es in CMake beschrieben wurde.

Fazit

Mit den CMake-Launch und CTest-Launch Einträgen kann ich also das gesamte GATE Projekt auf jeder unterstützten Plattform debuggen. Gesetzte Breakpoints werden der gewählten Debug-Session übergeben und nun kann man in VSCode fast genau so schön arbeiten wie unter Visual Studio selbst.

Der große Vorteil liegt in der Plattformunabhängigkeit. Einziger Nachteil ist die etwas mühsamere Verwaltung über JSON Dateien.

Leider gibt es bei komplexeren Systemen mit Abhängigkeiten auch wieder ein paar Probleme.
z.B. mit Conan.
Aber das ist eine andere Geschichte.

📧 📋 🐘 | 🔗 🔔
 

Meine Dokus über:
 
Weitere externe Links zu:
Alle extern verlinkten Webseiten stehen nicht in Zusammenhang mit opengate.at.
Für deren Inhalt wird keine Haftung übernommen.



Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!