Friday, June 01, 2018

"Windows Subsystem for Linux" (also known as "Bash on Ubuntu on Windows") AKA Windows 10 bash

"Windows Subsystem for Linux" (also known as "Bash on Ubuntu on Windows")

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  ‎Principal Program Manager, MSVC Compiler and Tools - ‎Microsoft
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.
Install/Enable the Windows Subsystem for Linux
Enable the "Windows Subsystem for Linux" optional feature and reboot.
Open PowerShell as Administrator and run:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
Start bash
Windows Menu type or search bash
-- Beta feature --
This will install Ubuntu on Windows, distributed by Canonical
and licensed under its terms available here:
Type "y" to continue: y
Downloading from the Windows Store... 100%
Extracting filesystem, this will take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit:
Enter new UNIX username: gps
Password: brcm1234
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
Connect your build system for Linux to use port 22
username gps
password brcm1234

How connect to your Visual Studio

Getting Started

Visual C++ for Linux Development

Setting up your project for Linux Development

With this workload you can author C++ code for Linux servers, desktops and devices. You can manage your connections to these machines from within VS. VS will automatically copy and remotely build your sources and can launch your application with the debugger. Our project system supports targeting specific architectures, including ARM.

Connecting to Linux


Today we only support building remotely on the Linux target machine. We are not limited by specific Linux distros but we do have dependencies on the presence of some tools. Specifically, we need openssh-server, g++, gdb and gdbserver. Use your favorite package manager to install them, e.g. on Debian based systems: sudo apt-get install openssh-server g++ gdb gdbserver

First connection

The first time you target a Linux machine you will be prompted for connection information. This is triggered by building the project.
On your Visual Studio go to Tools > Options > Cross Platform > Linux and enter the credential
  • Hostname: IP or hostname of your docker host
  • Port: The port you have pass in the previous command ( 12345 for example)
  • Username: gps
  • Authentication type: password
  • Password: brcm1234

Adding and removing connections

To add a new connection, go to Tools > Options and search for Connection, Connection Manager will be under Cross Platform. From here you can add and remove connections.

To change which connection a project is using go to the project properties general settings and update the Remote Build Machine option.

Project Properties

All of the options necessary to control C++ compilation are exposed on the project properies pages. We'll cover a few specific to how things work for Linux. First under general settings, you will see the remote root is set to ~/projects/ by default and that we are setting the remote project directory to match our project name in that location.

Looking at the General settings for the project, you can see how our output and intermediate directories were configured. Additionally, you’ll see that this project was configured as an application – thus our executable is under bin/x64/Debug/ as ConsoleApplication1.out. Notice that for configuration types we also support static and dynamic libraries.
Add additional library dependencies on the Linker > Input property page.

You can pass additional pre launch commands to the debugger to do things like launch graphical apps on the remote linux machine.

You can also send post build events to control remote behavior, as in this example that exports a gpio pin for use without requiring the executable run as super user.

Console window

The Linux workload has a console window tailored for interacting with your remote executables. This window shows not just the output of your program but can also take input. To activate this window, use the menu Debug, Linux Console.

Now you can attach to gdbserver running inside bash ubuntu on your local Windows 10

GNU gdb (GDB) 7.9
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-mingw32 --target=x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
Find the GDB manual and other documentation resources online at:
For help, type "help".
Type "apropos word" to search for commands related to "word".
Loaded 'shared libraries loaded at this time.'. Cannot find or open the symbol file.
Stopped due to shared library event:
  Inferior loaded /lib/x86_64-linux-gnu/
Loaded '/lib/x86_64-linux-gnu/'. Cannot find or open the symbol file.
Loaded '/lib64/'. Cannot find or open the symbol file.
Breakpoint 1, main () at /home/gps/projects/ConsoleApplication1/main.cpp:5
Kill the program being debugged? (y or n) [answered Y; input not from terminal]
The program '' has exited with code 0 (0x0).