CONAN und Remote Debugging
« | 14 Aug 2021 | »Neulich hat mich noch das Debugging in Visual Studio von CONAN Projekten beschäftigt und eine einfache CMake Variable löste das Rätsel.
Doch wie geht man das Problem unter
Linux an?
Oder: Wie löst man das Abhängigkeitsproblem mit
Visual Studio Code?
Das “normale” Visual Studio
bietet zwar seit einiger Zeit Linux Debugging an, aber man muss dafür eigene
Projekte generieren, was mit CMake
aktuell schlecht bzw. gar nicht
zusammenspielt.
Oder man hängt sich in ein bereits “vorbereitetes” CMake
Projekt via
SSH rein, aber genau das
funktioniert wieder nicht mit Projekten, wo CMake seine Abhängigkeiten von
CONAN hereinbekommt.
Nachdem Visual Studio Code nun endlich auch am Raspberry PI
halbwegs stabil läuft, bin ich mehr und mehr von CodeBlocks
und K-Develop zu VS-Code
übergegangen.
Das war anfangs mühsam weil diese “leere” IDE mit seinen zusammengestückelten
Tasks-Aufrufen den “richtigen” IDEs unterlegen war.
Langsam gewöhne mich aber daran und je länger man damit arbeitet um so eher
akzeptiert man diese Eigenheiten.
Das CONAN Dependency Problem
Wenn CONAN
unser CMake
aufruft um die Projektstrukturen zu generieren,
werden Include- und Link-Pfade korrekt gesetzt und die Builds sollten damit
auch super laufen. Doch wenn man das fertige Programm im Debugger
durchlaufen lassen will, schlägt der CONAN
Hammer wieder zu:
Alle abhängigen Komponenten (*.dll
, *.so
) liegen im CONAN
Cache und das
gebaute Programm steht alleine da.
Die Lösung ist mit conan install .... -g virtualrunenv
diverse Scripts zu
generieren, die alle Abhängigkeiten in den Pfad (PATH
, LD_LIBRARY_PATH
,
DYLD_LIBRARY_PATH
) laden können.
Das Problem bei diversen IDEs und auch VS-Code ist, dass ein Debugging-Prozess
nichts von diesen CONAN
Script weis und das zu debuggende Programm falsch
startet und gleich wieder abbrechen muss.
Lösung: Environment in den Debugger importieren
Wenn man nach einem ausgeführten conan instal .... -g virtualrunenv
gleich
im Anschluss source activate_run.sh
aufruft, hat man die notwendigen
Environment Variablen für eine Debugging-Session in der Shell gesetzt.
Man kann sich diesen Zustand z.B. per
echo LD_LIBRARY_PATH=$LD_LIBRARY_PATH > saved_paths.env
sichern.
Kaum ist die Ausführung abgeschlossen gehen die Variablen wieder verloren,
aber die .env
Datei bleibt.
In launch.json
kann man durch das Feld envFile
die zuvor gesicherten
Variablen zurückholen und in der Debug-Session benutzen.
Und schon kann ein debug-tes Programm seine CONAN
Abhängigkeiten finden.
Wenn das Programm auch eigene parallel geladene Libs laden können muss,
dann kann man diese Pfade auch selbst zusammenstellen und per Shell-Script
in der env
Datei anfügen. z.B.: mit
Und so kann das ganze dann am Ende aussehen:
1//tasks.json 2{ 3 "version": "2.0.0", 4 "tasks": [ 5 { 6 "label": "conan-install", 7 "type": "shell", 8 "command": [ 9 "conan install ${workspaceFolder} -if ${workspaceFolder}/build", 10 " && conan install ${workspaceFolder} ", 11 "-if ${workspaceFolder}/build -g virtualrunenv", 12 " && source ${workspaceFolder}/build/activate_run.sh", 13 " && echo ", 14 "LD_LIBRARY_PATH=${workspaceFolder}/build/bin:$LD_LIBRARY_PATH ", 15 ">${workspaceFolder}/build/conan-libs.env", 16 " && echo DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH ", 17 ">>${workspaceFolder}/build/conan-libs.env" 18 ] 19 }, 20 { 21 "label": "conan-build", 22 "type": "shell", 23 "command": [ 24 "conan build -if ${workspaceFolder}/build ", 25 "-bf ${workspaceFolder}/build ", 26 "-sf ${workspaceFolder} ${workspaceFolder}" ], 27 "problemMatcher": [ ], 28 "group": { 29 "kind": "build", 30 "isDefault": true 31 } 32 } 33 ] 34}
1//launch.json 2{ 3 "version": "0.2.0", 4 "configurations": [ 5 { 6 "name": "(gdb) Launch", 7 "type": "cppdbg", 8 "request": "launch", 9 "program": "${workspaceFolder}/build/bin/my_binary", 10 "args": [], 11 "stopAtEntry": false, 12 "cwd": "${workspaceFolder}/build/bin", 13 "environment": [], 14 "externalConsole": false, 15 "MIMode": "gdb", 16 "setupCommands": [ 17 { 18 "description": "Enable pretty-printing for gdb", 19 "text": "-enable-pretty-printing", 20 "ignoreFailures": true 21 }, 22 ], 23 "envFile": "${workspaceFolder}/build/conan-libs.env" 24 } 25 ] 26}
Fazit
Nun, Mission erfüllt. Wieder ein CONAN
Brocken aus dem Weg geräumt …
oder sagen wir mal, wir haben einen Workaround dafür gefunden.
Mir wäre es lieber, es gäbe ein CONAN
-Plugin, dass sich um solche lästigen
Details automatisch kümmert, doch aktuell schafft man mit Boardmitteln
nur kleine Hello-World CONAN
Programme zu debuggen.
Sobald die Abhängigkeiten zunehmen bleibt einem (laut meinem aktuellen Stand)
nichts anderes übrig, als per Scripts alles so hinzubiegen,
dass es halbwegs läuft.
Das ist zwar aus meiner Sicht unbefriedigend … aber zumindest ist es mal ein Anfang.