Tag Archives: Linux

Using VS Code to Debug Linux Makefile Projects

Posted 20 February 2024,

I recently got re-interesting in soaring (glider racing) after a number of years away. As part of this new journey, I became interested in contributing to the development of the XCSoar glider racing navigation software. I had contributed to this program some years ago in a very minor way, and thought maybe now that I’m retired and have plenty of time to waste (NOT!!), I could maybe contribute in a more meaningful way.

In any case, XCSoar development is done in Linux (Specifically in Debian Linux, but that’s another story), so I started thinking about creating a development environment on a Debian Linux box. I had an old Dell Precision M6700 ‘desktop replacement’ laptop that I hadn’t turned on for years, so I dug it out, installed Linux (Ubuntu first, then Debian), and with the help of Ronald Niederhagen (see this post), I was able to clone the XCSoar repo from Github and built both the Linux and Android versions.

However, I still needed to find a way to ‘break into’ the code, and to do that I was going to need a way of running the program under debug control. I have done this sort of thing for decades on the Windows world, but not so much in Linux, so I was sort of starting from scratch. After a LOT of research, I found that Microsoft had a free Linux IDE called VS Code – sort of a lightweight version of Visual Studio aimed at the Linux and IOS world.

So, I installed VS Code on my Linux box and started the ‘lets learn yet another coding IDE’ dance, again starting with a lot of Google searches, running tutorials, etc etc. After creating some basic ‘hello world’ programs using VS code, I started thinking about how to use VS Code on the XCSoar project, comprised of thousands of source files and a Makefile almost three hundred lines long. I knew just enough about Makefiles to type ‘make’ or ‘make all’, so there was a steep learning curve ahead to use VSCode for debugging.

After yet another round of Google searches and forum posts, I found a relevant tutorial on the ‘HackerNoon’ website. the HackerNoon tutorial seems to be aimed at Windows users (Linux doesn’t use extensions to denote executable files), but I was able to work my way through and translate as appropriate. I suggest you open the HackerNoon tutorial in one window, and this ‘translation’ in another.

Original:

Translation for Linux:

Download & Install VS Code: See this link. Everything else should already be available as part of any modern Linux distro (I’m using Debian 12 – ‘bookworm’).

main.cpp: (same as original – no translation required)

Makefile (Original):

Makefile (Translation for Linux):

Run the ‘main.exe’ make target, then run the executable to make sure everything works (Original):

Translation for Linux:

I placed ‘mymain.cpp’ and ‘Makefile’ in my home directory tree as shown below:

so to test the Makefile and the executable, I did the following:

This test confirms that the source code compiles correctly, that the Makefile is correct, and the output from the compiled program is as expected – yay!

Setting up VSCode debugger:

At this point the HackerNoon tutorial and my experience parted ways. I could get the ‘Run and Debug’ side panel open, and I could open ‘mymain.cpp’ in the VSCode editor window, but I couldn’t find anything that suggested it could “create a launch.json file”. I tried to send a comment to the author, but comments weren’t enabled for some reason (and yes, I did register and log in). I suspect that the disparity between the HackerNoon example and my VSCode reality is due to changes in VSCode after the HackerNoon tutorial was created. Which is why I absolutely hate posts like this that aren’t dated in any way shape or form. Because of this, it is impossible to determine if changes like I encountered are due to mistakes on the part of the author, or just changes in the underlying software being demonstrated.

So, I was left to randomly click on things until, by some miracle, the ‘launch.json’ file was created and appeared in the VSCode edit window. Later I went back and tried to re-create the miracle and I sort of figured it out; with the ‘mymain.cpp’ file open in the editor, click on the ‘gear’ icon (upper right as shown in the screenshot below):

And select ‘(gdb) Launch’ from the menu items presented. This will create a ‘launch.json’ file and open it in the editor, as shown below:

launch.json file created by VSCode

At this point we can reconnect to the ‘HackerNoon’ tutorial and copy/paste the launch.json contents from the tutorial to the newly-created launch.json file in VSCode, as shown below

launch.json after copy/pasting example code from HackerNoon site

Here’s the ‘launch.json’ file from HackerNoon:

And here’s the same file, after translating it for Linux instead of Windows:

The next step is to create a ‘tasks.json’ file using the ‘New File’ (ALT-Ctrl-N) in VSCode. This brings up a dialog forcing the user to specify the folder into which the new file will be placed, which seemed a bit strange for me, but what do I know. Put the new file in the same (hidden) .vscode folder as the companion ‘launch.json’. In my setup this was layed out as shown below:

Here’s the original ‘tasks.json’:

And here’s the same file after translation for Linux:

The above three files (mymain.cpp, launch.json and tasks.json) form a complete set (a ‘configuration?) that enables VSCode to compile and then run – under debug control – a .cpp file. Here’s a short video showing two complete compile/run cycles:

Video showing VSCode compiling/running/debugging using a Linux Makefile

At this point is is clear that the combination of VSCode, in conjunction with appropriately constructed ‘Makefile’, ‘launch.json’ and ‘tasks.json’ files is capable of debugging a Linux-base C++ program. This means that – at least in theory – I should be able to aim VSCode at the humungous Makefile associated with the equally humungous XCSoar program and step through the source code under debug control – yeeehah!

23 February 2024 Update:

Well, the theory (about being able to run XCSoar under debug control) has now been validated. I was able to run XCSoar using the following launch & tasks.json file contents

Launch.json:

Tasks.json:

And here is a short video showing the action:

So now I’m set; I can run XCSoar under debug control, and I should be able to poke around and hopefully make some changes (or at least understand some of the magic tricks). On thing I’ve already found is that (depending on where the breakpoints are) XCSoar can grab the mouse focus (not the keyboad, thankfully), so even though the mouse cursor can move around the screen outside the XCSoar window, all mouse clicks go to XCSoar. Fortunately I found that keyboard inputs still go to VSCode, so I can still (with some difficulty) get around OK.

Connect Condor on PC to XCSoar on Linux

Posted 17 January 2024

I recently re-started flying Condor Soaring Simulator after a long absence, and renewed an old interest in using the open-source XCSoar navigation software for external TAT/AAT planning and navigation. XCSoar runs on PC’s, Android phones/tablets, and Linux and is widely used in RL (real-life) and Condor soaring.

I started out by running XCSoar 7.42 on a cheap Android M10 tablet, connected via Bluetooth to Condor running on my Windows 10 PC. Then I created a small AAT task in the default Slovenia scenery and ran a series of test flights to see how XCSoar did. I documented my results in this post and this one.

As a result of my study, I identified some bugs and other issues on the XCSoar forum, and found out that the XCSoar software is actually written in C++ on Linux, and then cross-compiled for the various supported platforms. I’ve done a fair bit of work in C++ and in Linux, so this got me thinking that maybe I could resurrect my old Linux skills and play around with the XCSoar source code a bit. So I dug out my old moth-balled Dell Precision M6700 laptop, loaded up Ubuntu 24.0 LTS, cloned the XCSoar repo, compiled it on my Linux box, and voila! I was in business!

Well, not quite. In order to use Condor on my Windows PC as the test bed for XCSoar software mods, I had to somehow connect Condor’s NMEA output to the NMEA input to the XCSoar program running on my Linux box. This turned out to be non-trivial and involved a lot of web searching, tearing of hair (what little I have left), and gnashing of teeth, but in the words of my Nebraska cousins “We gotter done!”

This post, then is a way of capturing the surprisingly easy (once you know the magic) process of connecting the NMEA output from Condor running on my Win 10 PC to the NMEA input of XCSoar running on my Linux box.

As it turned out, I had already solved (sort of) the first half of the problem, getting NMEA data from Condor out of my Win 10 PC. When I first (re)started playing with XCSoar, I found some posts describing how to connect Condor NMEA ouput to XCSoar running on the same PC, using a nice utility called ‘Virtual Serial Ports Emulator’ (VSPE), and this actually worked very well – except for one tiny little problem; in order to make any adjustments in XCSoar, I had to ALT-TAB out of Condor over to XCSoar, and that meant ‘flying blind’ (literally) while working with XCSoar – not a good thing. I solved this problem by instead route Condor NMEA output to a Bluetooth virtual serial port connected to an Android M10 tablet.

The procedure for connecting Condor on my Win 10 PC to XCSoar running on a Linux box is:

  • Connect Condor NMEA output to a TCP port on the Win 10 Box
  • Use ‘socat’ on the Linux box to connect the Win 10 TCP port to XCSoar

Connect Condor NMEA output to a TCP port on the Win 10 Box:

This connection is composed of two legs, both using VSPE; the first one defines a virtual serial port to which Condor NMEA output can be directed. The second one creates a connection between the virtual serial port defined in the first step to a Win 10 TCP port. The screenshot below shows both these legs.

Any unused COM port number may be defined here. Once this is done, connect Condor NMEA output to this port by going to Setup->Options in Condor, checking the ‘Output NMEA’ box, and then selecting the port number defined above, as shown below:

Use ‘socat’ on the Linux box to connect the Win 10 TCP port to XCSoar:

When I first started this adventure, I found references to the Linux ‘socat’ command while Googling for things like “Connect Linux Box to Win 10 PC”. Then I started reading about ‘socat’ in particular, and although I could understand that ‘socat’ connected two ‘things’ (where a ‘thing’ could be a serial port, a TCP port a UDP port, a website, etc), it wasn’t easy to figure out how to use it for my application. Finally I ran across this tutorial, which guided me through a series of example socat applications.

After playing with the examples for a while, I realized I should be able to use the ‘STDIO’ socat example to connect the already existing TCP port on my Win 10 box to STDIO in a Linux console terminal and watch NMEA data flow through. So I fired up Condor on my PC and selected ‘Free Flight’. In the ‘NOTAM’ tab, I selected the ‘Airborne’ start option (I believe this is the default), and then selected ‘Start Flight’. Condor outputs NMEA sentences even when the glider is suspended in mid-air, waiting to start flying, so this is a convenient way to test connections. Then on my Linux box I opened a terminal window and typed in the command shown at the top of the following image:

Linux ‘socat’ command to connect Condor NMEA output to terminal window

When I executed the command, I started getting NMEA sentences from Condor – yay!!

Now that I verified that I can connect to a Linux terminal window from Condor running on my Win10 PC, the remaining piece is to change the destination from a terminal window to XCSoar’s GPS data input and then configure XCSoar to accept GPS data from that port. To do this I executed the following ‘socat’ command on a terminal window in Linux:

This establishes a connection between a randomly selected UDP port on the Linux box and a TCP port on my PC. The PC TCP port number is the one selected above connecting COM9 to a TCP port, and the UDP port on my Linux box was just a random unused port number.

Then I launched XCSoar on my Linux box and navigated to Config–>Devices, as shown in the following screenshot. Device A is defined as UDP port 4353, the port number selected above.

XCSoar ‘Devices’ page showing connection to Linux UDP port 4353

This establishes the end-to-end connection between Condor running on my Win10 PC to XCSoar running on my Linux box. With this established, XCSoar shows ‘GPS fix’ as the status for Device A, and the main screen shows the glider’s location in the selected scenery, as shown below:

Stay Tuned,

Frank