Visual C++ for Linux Development

Published on Wednesday, July 20, 2016

Visual C++ for Linux Development is the Visual Studio 2015’s extension by Microsoft that lets us write C++ code in Visual Studio for Linux machines and devices. It connects to the machine or device over SSH and uses machine / device’ g++, gdb and gdbserver to provide compilation and debugging experience from within Visual Studio. After installing the extension; it adds Linux Connection Manager into Visual Studio’s Options dialog through which we manage the SSH connections to Linux machines or devices (ARM also supported). It also adds the project types; currently there are three; Blink (Raspberry), Console Application (Linux) and Empty Project (Linux). You can write the C++ code using Unix headers and libraries. For intellisence / removing red squiggles; you will need to download the header files (using PUTTY’s PSCP) to the development machine and add that folder in the project properties’ VC++ Directories section

Linux Connection Manager

We can use this extension with Docker Container as well; all we need is an image having SSH Server (OpenSSH), g++, gdb and gdbserver. I created this Dockerfile

FROM ubuntu:trusty
MAINTAINER Khurram <khuziz@hotmail.com>

RUN apt-get update && apt-get -y upgrade
RUN apt-get -y install openssh-server
RUN apt-get -y install g++
RUN apt-get -y install gdb gdbserver
RUN apt-get -y install nano iputils-ping

RUN mkdir /var/run/sshd
RUN echo 'root:root' | chpasswd
RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

  • For some wiered reason; g++ installation was failing on latest ubuntu; therefore used ubuntu:trusty as base image
  • We need to set root password and configure OpenSSH to allow direct root ssh
  • 22 SSH port is exposed; that we can map to Docker Host Machine
  • SSHD is started using CMD with –D flag so detailed logs get created in case Visual Studio fails to connect to it and you need troubleshooting

Once the image is built; you can run it with the following docker run command; I have also uploaded the image on to the Docker Hub, so you can directly use the following docker run command and it will download the prebuilt required image for you automatically

docker run –name linuxtools –v /root/projects –p 2222:22 –d khurramaziz/linuxtools

  • We cant map exposed 22 port to host’s 22 port as there’s (usually) already SSH server running on host’s 22; so mapping it to 2222 instead
  • Used –d option to run it in background
  • Notice I have mounted /root/projects as Docker Volume; this is where the extension upload project files and compile and place the built binaries, I have also named the container so that I can use volumes-from when running other Containers later to test the built binaries

Once the container is up and running we can SSH to it; if using putty; use –P flag to specify the port; putty –P 2222 YourDockerHost; and if its working fine; we can set up its connection in Visual Studio’s Linux Connection Manager. When everything is in order; we can build our project; if we doe the DEBUG build; our HelloLinux binary will be at /root/projects/HelloLinux/bin/x64/Debug/HelloLinux.out that we can run from the SSH

SSH

Given we have the binary on the volume; we can run other containers, mounting the volume and run the ELF64 binary and it will run fine

Containers

If you try to run the compiled binary on a plain official busybox Container; it will fail as it doesn't have the required C libraries. Either add --static (dash dash static) in the Linker settings (Project Properties) or there is busybox:ubuntu-14.04 (5.6Mb comparing to 1Mb) Docker Image with all the C libs in place. Your Dockerfile will be something like this

FROM busybox:ubuntu-14.04
COPY HelloLinux/bin/x64/Release/HelloLinux.out /hello
CMD ["/hello"]

Resources