profile pic

Precise Asteroid

Welcome to Amir's Blog 👋

Local Client Remote Code

2020-05-11

At first I found coding C++ on mac inconvinent. I still find it so 🤷 Couldn't really get VSCode to debug properly like Udacity suggest, so I therfore opted for Xcode. Not ideal, but at least it worked.

But then the 2nd project was about writing a Htop like app for Linux. That means that you can't even run and debug on Mac by defintion.

Since I did not want to Udacity's hosten linux enviroment and wanted to develop localy, I ran into the following combination that is very promising

Developing with the local VSCode client on map but on remote linux server. More precisly Ubuntu's Multi Pass.

Multipass?

Multipass is a fast and easy to run ubuntu VM on your machine. saved me all the VirutalBox hassle of downloading ubuntu image and installing OS. 5 min and you are up and running.

Setting Multipass for VSCode

Install Multipass and start the (primatry) server

Mutlipass

Now cheack that you could ssh to the instance. first get the ip address by running multipass list

XYZ@Amirs-MacBook-Pro NewThing % multipass list
Name                    State             IPv4             Image
primary                 Running           192.168.64.2     Ubuntu 18.04 LTS

First time I tried that, I got a permission denied response. In order to bypass that, just copy your default public kye, located under ~/.ssh/id_rsa.pub to the host ~/.ssh/authorized_keys.

Then the following should work:

XYZ@Amirs-MacBook-Pro NewThing % ssh ubuntu@192.168.64.2

That's important, as VSCode will later go through the same process when trying to SSH.

In order to build the original code, I had to install also the following applications that do not come with the multipass instance

  • g++
  • cmake

Setting VSCode

Ok, Now we are ready to start handling VSCode. I started by cloning a repo to the remote instance.

Then install the Remote-SSH extention.

Then trigger the command Connect to SSH

connect

Add new SSH Host...

ssh host

Place the same ssh string you tried earlier in the terminal

ssh host

Pick a configuration to store it in. I picked my user's.

ssh host

You would then get a pop up that allows you to connect. hit connect.

ssh host

Enter the passphrase you used when generating to id_rsa.pub.

ssh host

That is! The remote folders, as well as the local ones, are available for opening.

ssh host

ssh host

Building and running the application

Here it depends on the toolchain one uses. Since this excercise uses make (build and debug for the different use-cases) all I needed is to crete a task

Here is my tasks.json file:

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "build make",
            "command": "make",
            "args": [
                "build"
            ],
            "group": "build"
        },
        {
            "type": "shell",
            "label": "build debug",
            "command": "make",
            "args": [
                "debug"
            ],
            "group": "build"
        }
    ]
}

Then all you need to do, is run build task... and the application builds

Debugging the application

Must admit that it took me a long time to get that running. It is only till I came across this post and the movie it points to, that my path was unblocked.

But let's start from the start. Here is my luanch.json file

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "debug application",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/monitor",
            "args": [],
            "stopAtEntry": true,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "miDebuggerPath": "/usr/bin/gdb",
            "preLaunchTask": "build debug",
        }
    ]
}

Pay attention to two things:

  1. miDebuggerPath: turns out the multipass instance comes without GBD. so you'd have to install it
  2. preLaunchTask: see how I run the debug task before starting the debugger

And here is to the viola moment: turns out you need to run the clean task for.

So here is my final taaks.json with all the tasks

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "build make",
            "command": "make",
            "args": [
                "build"
            ],
            "group": "build"
        },
        {
            "type": "shell",
            "label": "build debug",
            "command": "make",
            "args": [
                "debug"
            ],
            "group": "build"
        }
        ,
        {
            "type": "shell",
            "label": "build clean",
            "command": "make",
            "args": [
                "clean"
            ],
            "group": "build"
        }
    ]
}

And then all you need to do is run the start debugging command

ssh host

Made by Amir 💚