Scott Hanselman

Writing and debugging Linux C++ applications from Visual Studio using the "Windows Subsystem for Linux"

April 03, 2017 Comment on this post [17] Posted in Linux | Open Source | Win10
Sponsored By

I've blogged about the "Windows Subsystem for Linux" (also known as "Bash on Ubuntu on Windows") many times before. Response to this Windows feature has been a little funny because folks try to:

  • Minimize it - "Oh, it's just Cygwin." (It's actually not, it's the actual Ubuntu elf binaries running on a layer that abstracts the Linux kernel.)
  • Design it - "So it's a docker container? A VM?" (Again, it's a whole subsystem. It does WAY more than you'd think, and it's FASTer than a VM.)

Here's a simple explanation from Andrew Pardoe:

1. The developer/user uses a bash shell.
2. The bash shell runs on an install of Ubuntu
3. The Ubuntu install runs on a Windows subsystem. This subsystem is designed to support Linux.

It's pretty cool. WSL has, frankly, kept me running Windows because I can run cmd, powershell, OR bash (or zsh or Fish). You can run vim, emacs, tmux, and run Javascript/node.js, Ruby, Python, C/C++, C# & F#, Rust, Go, and more. You can also now run sshd, MySQL, Apache, lighttpd as long as you know that when you close your last console the background services will shut down. Bash on Windows is for developers, not background server apps. And of course, you apt-get your way to glory.

Bash on Windows runs Ubuntu user-mode binaries provided by Canonical. This means the command-line utilities are the same as those that run within a native Ubuntu environment.

I wanted to write a Linux Console app in C++ using Visual Studio in Windows. Why? Why not? I like VS.

Setting up Visual Studio 2017 to compile and debug C++ apps on Linux

Then, from the bash shell make sure you have build-essential, gdb's server, and openssh's server:

$ sudo apt update
$ sudo apt install -y build-essential
$ sudo apt install -y gdbserver
$ sudo apt install -y openssh-server

Then open up /etc/ssh/sshd_config with vi (or nano) like

sudo nano /etc/ssh/sshd_config

and for simplicity's sake, set PasswordAuthentication to yes. Remember that it's not as big a security issue as you'd think as the SSHD daemon closes when your last console does, and because WSL's subsystem has to play well with Windows, it's privy to the Windows Firewall and all its existing rules, plus we're talking localhost also.

Now generate SSH keys and manually start the service:

$ sudo ssh-keygen -A
$ sudo service ssh start

Create a Linux app in Visual Studio (or open a Makefile app):

File | New Project | Cross Platform | Linux

Make sure you know your target (x64, x86, ARM):

Remote GDB Debugger options

In Visual Studio's Cross Platform Connection Manager you can control your SSH connections (and set up ones with private keys, if you like.)

Tools | Options | Cross Platfrom | Connection Manager

Boom. I'm writing C++ for Linux in Visual Studio on Windows...running, compiling and debugging on the local Linux Subsystem

I'm writing C++ in Visual Studio on Windows talking to the local Linux Subsystem

BTW, for those of you, like me, who love your Raspberry Pi tiny Linux computers...this is a great way to write C++ for those little devices as well. There's even a Blink example in File | New Project to start.

Also, for those of you who are very advanced, stop using Mingw-w64 and do cool stuff like compiling gcc 6.3 from source under WSL and having VS use that! I didn't realize that Visual Studio's C++ support lets you choose between a number of C++ compilers including both GCC and Clang.


Sponsor: Thanks to Redgate! Track every change to your database! See who made changes, what they did, & why, with SQL Source Control. Get a full version history in your source control system. See how.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
April 04, 2017 0:20
I've been toying with this on and off and find it neat and maybe even a good (and free) alternative to VisualGDB.

In my situation, I have a 500+ source project with 14 static/dynamic libs in a CMake build system. If I want the full debugging experience (breakpoints, stepping, variable inspection, etc) on Linux, I must import the source, project, etc into these Visual Studio Project templates (eg Makefile Project template). It would be a lot of work and maintenance just for debugging within VS. If there is automation of this, it was beyond anything obvious with some web searches.

The perfect OOB scenario, would be to have VS 2017's new CMake integration, support this debugger. One build system to maintain. One VS instance. One VS "solution" (File->Open Folder). Compile/debug "all" platforms I target.
April 04, 2017 1:03
Any plans to support this as a build configuration rather than (just) as a separate project type, so that you could use VS to seamlessly code, debug, and test a cross-platform C++ project?
April 04, 2017 3:46
Are there any plans to run docker containers on "Windows Subsystem for Linux" instead of MobyLinux running in a VM?
April 04, 2017 6:50
So if I'm understanding you correctly, then WSL is more like WINE in that the subsystem layer is intercepting the Linux system calls and converting them to something more Windows-friendly. Neat!
April 04, 2017 11:13
This makes me want to try it out. I used zsh when I was using Linux until recently. If that is supported here, then I am definitely up for it!
April 04, 2017 11:44
This is a step closer to me being able to use this at work. As with some of the other comments I work on a large project with many projects and hundreds of existing source files. To set this up would be a massive undertaking.

It would be good if in the future the cmake integration could automagically pull in the source and other dependencies for us. The we could just tell VS to open a cmake project, plug in our cmake build arguments and go.

Another thing is the build and debug. We currently cross compile to x86_64 and ARM then copy the application to a device to debug it. There's not really any way to do that from within VS at the moment. For now we're stuck with a VM and Eclipse :(
April 04, 2017 18:51
Did you install Upstart elsewhere as SSH will not start with the steps indicated.

initctl: Unable to connect to Upstart: Failed to connect to socket /com/ubuntu/upstart: Connection refused
April 05, 2017 0:56
Has anyone been able to install dotnet core on Bash on Windows?

I'm getting the following error when running sudo apt-get update after doing the previous steps on dot.net:

W: Failed to fetch https://apt-mo.trafficmanager.net/repos/dotnet-release/dists/trusty/main/binary-amd64/Packages gnutls_handshake() failed: Handshake failed

April 05, 2017 1:23
I'm the PM for the VC++ support for Linux. I hear the requests for cmake. You may have seen we added cmake support to VS2017, but today that only works for our Windows compilers. We are looking at what we need to do to extend that support to Linux as well.

Since we don't have that today I did provide some bash scripts that can generate our current makefile projects from your existing code bases. You can use this to invoke whatever build process you have on the Linux side. I normally git clone in bash on my windows box then run these scripts.

If you want to reach me or our dev team directly you can find us at vcpplinux-support microsoft.com
April 05, 2017 9:02
Andy - Run "lsb_release -a" and make sure you know what Ubuntu you're running. I was running 16.04 on my Windows 10. Trusty (mentioned in your error) is 14.04.
April 05, 2017 16:57
Yeah, I had done that and I am running Trusty. That's interesting. I'll look into updating the kernel (or reinstalling the bash on windows feature). Thanks.


ap:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.4 LTS
Release: 14.04
Codename: trusty
April 05, 2017 17:44
For me, I think the exciting takeaway is that VS can connect to a remote system to run a build. The ability to do that on the WSL is cool in itself, but I've been missing the GUI when working over SSH.

I'm not seeing that in VS2015 though, I assume this is new to VS2017.
April 06, 2017 3:15
Has anyone looked into if this works, or if there is a workflow to use with Yocto projects? Would be interesting to eliminate the need for a Linux VM.
April 07, 2017 0:03
At least in earlier Windows 10 versions, after you install Bash on Windows an SSH service gets installed and setup to run automatically on boot. So it may be a security risk after all.
April 07, 2017 7:54
The WSL and the WINE project seem to be building the same mapping of system calls from opposite directions. I've heard that the MS folks have learned from the Samba project. I'd like to think that some healthy cross-pollination is happening with WSL and WINE, as well.

April 10, 2017 2:12
Mike K - from my reading about this project, windows subsystem for Linux is a misnomer. It's an NT subsystem. NT had subsystems for os/2, windows, and now Linux. It does translate Linux syscalls to nt syscalls, and does extra work where a direct mapping isn't available. I'm sure more knowledgeable people can come in if I'm glossing over something important. I followed one of the earlier how tos to get redis running, it was super easy. Now my work just needs to move us off of win 7 :(
April 16, 2017 16:55
Is it possible to step into glibc and into Standard C++ library?

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.