Coding & Testing Linux Applications on Windows using WSL and VS Code
In this article, I will share my experience of using Windows Subsystem for Linux along with Visual Studio Code for some basic coding and testing in C++ & Java. Whilst I will be using some of the examples from the Refinitiv Real-time SDKs — the notes below should be applicable to general C++ and Java development.
I will start with
- an overview of some key relevant WSL + VS Code features I discovered
- followed by the detailed steps I carried out in order to be able to edit, compile and run C++ & Java examples inside the WSL environment.
Knowledge Prerequisite — working knowledge of Windows, developer tools such as make, JVMs and a basic understanding of Linux console usage
A Windows diehard!
I have been a Windows developer for most of my career — I started with MS-DOS-based development before quickly moving onto Windows development. I may have interacted with a SQL Server or Oracle systems over the years, but these would have always been via a Windows-based interface/utility.
When I joined Reuters back in 2004 I discovered that our real-time streaming APIs came in both Windows and Linux versions and most of our clients’ real-time data applications were deployed on Linux — which makes sense — improved performance and stability compared to Windows (certainly back then).
So, I had to adapt and start familiarising myself with Linux. But for someone who had spent most of their working life with Windows and MS-DOS, this did not come easy. I seriously struggled — the joys of Vi, the considerable difference between cmd.exe and the various Linux shells etc. When possible I always did my coding or tried recreating a customer issue on Windows. If all worked OK on Windows, then I would migrate it to Linux or try and recreate the issue on Linux as required. I had to rely on tools like WinSCP and PuTTY to transfer files and access our Linux test machines.
It’s not like I did not want to learn Linux — just the infrequent usage and lack of time meant I never made any reasonable progress.
Things got a bit easier with virtualisation products such as VMWare and VirtualBox — allowing me to use a GUI interface with Linux and only resort to a Linux shell when I absolutely had to. However, there was always the issue of reduced performance and the headache of maintaining the VM, configuring the network settings etc and VMs that mysteriously stopped working…
Some of you may ask ‘What about Docker?’- we have published some Docker Container Images for our Real-Time SDKs (see links below) which I find useful for basic testing. However, I personally did not find that Docker offered me the same flexibility and integration suited to my workflow.
Windows Subsystem for Linux
You can imagine my hopefulness when I first started hearing the great promises Microsoft were making around their new Windows Subsystem for Linux.
My first experiments around WSL simply involved copying across the Linux versions of our SDKs and trying to build and run them. Any coding/editing was still done on Windows and copying the files/changes back and forth between Windows to Linux as required.
Initially, I was typing long winded command lines like:
cp /mnt/c/Refinitiv/RTSDK-2.0.2.L1.win.rrg/Cpp-C/Ema/Examples/Training/Consumer/100_Series/100_MP_Streaming/Consumer.cpp .
before I discovered the WSL File Explorer integration.
The integration works really well — allowing you to access the WSL directory structure from Windows File Explorer by navigating to Network->wsl$ — if you cannot see the wsl$ share then just type in wsl$ into the address bar and then selecting the required WSL installation (you will note below that I got carried away and installed four WSL versions):
You can then navigate the Linux directory structure using Windows File Explorer — below I have navigated to my Linux home directory and into the RT-SDK directory:
Alternatively, from a WSL terminal, you can invoke File Explorer by typing in explorer.exe . — where the dot specifies the current Linux directory:
which brings up file explorer in the same directory as the WSL terminal:
Visual Studio Code WSL Integration
Whilst I used full-blown Visual C++ for my Windows RT-SDK C++ coding etc, around the same time as I was exploring WSL, I had also started using Visual Studio Code for editing and running Python scripts — it starts up quicker and Microsoft is continuously improving the Python integration with VS Code.
At some point, VS Code alerted me to the existence of a WSL extension — Remote — WSL — which ‘allows VS Code on Windows to build Linux applications that run on WSL’. After installing and checking out the extension, I initially felt the phrase ‘build Linux applications’ was a bit of an exaggeration — nonetheless, the ability to directly edit source code in my WSL file system directly from a Windows IDE definitely scored points with me (no more manual having to navigate the $wsl — which to me seems slower than using VS Code + WSL extension).
It is worth noting here that the Remote — WSL extension is actually part of the VS Code Remote Development extension pack — which include SSH support and Docker integration.
Visual Studio 2019 and 2022 — Improved WSL Integration
If you are a C++ developer and have a full Visual Studio licence, then it gets even more interesting:
- Visual Studio 2019 version 16.1 added native support for using C++ with WSL
- Visual Studio 2022 introduces an improved WSL 2 toolset for C++ development — which allows you to build and debug C++ code on WSL
I did briefly try out the steps in the VS2019 blog post, but it did not work for me as described — will no doubt try again at a later date.
That’s the background covered, so let’s crack on and look at what I did in order to set up my C++ and Java dev environment on WSL.
Setting up a basic C++ Linux Dev environment on WSL
As you may have guessed, my primary objective was to be able to run build and run Linux versions of our APIs/SDKs such as the Refinitiv Real-Time SDK.
As the RT-SDK is qualified/tested with RHEL and other related distros such as Centos, Oracle Linux — I installed the Fedora Remix for WSL — which is available from both the Microsoft store and Github (see links below). I also briefly tested with Pengwin Enterprise WSL (upgraded to Oracle Linux) and that seemed to work fine too.
Enabling WSL and Installing a Linux distro
As there are plenty of online resources on how to install WSL on Windows, I will refer you to the Microsoft one that I used — Install WSL on Windows 10 | Microsoft Docs. At Step 6 of these instructions, you can install Fedora Remix from the Microsoft Store or GitHub — or another Redhat based distro such as Pengwin Enterprise or Centos (I have not tested with Centos or others).
Setting up our basic Linux Dev environment
Once I had complete my Fedora Remix WSL installation and set my root password etc, I had to carry out the following steps to install the basic development tools such as git, cmake, compiler etc (If you use a different distro, the installation requirements may vary based on what is already packaged with that distro).
Note that I will be installing the Refintiv Real-Time SDK in my Linux home directory (rather than the commonly used opt directory) — as the opt directory needs sudo permissions — and I don’t want to keep having to sudo or su root each time I want to change some source code etc.
Open up a WSL terminal and perform the following steps to
- install git
- install my c++ related tools
- clone the RT-SDK repository from GitHub
- install cmake
- get an XML library used by RT-SDK
# install git
sudo yum install git# install openssl and development package
sudo yum install openssl
sudo yum install openssl-devel# some development tools
sudo yum group install "Development Tools"# some distros include gcc-c++ in dev tools - so you may not need this step - but I did
sudo yum install gcc-c++# download clone the Refinitiv RT-SDK into my home directory (~)
cd~
git clone --recursive https://github.com/refinitiv/Real-Time-SDK.git# download and unpack cmake into the opt directory
cd /opt
sudo wget https://cmake.org/files/v3.21/cmake-3.21.0-linux-x86_64.tar.gz
sudo tar -xvf cmake-3.21.0-linux-x86_64.tar.gz# download XML Library
sudo wget http://xmlsoft.org/sources/libxml2-2.9.9.tar.gz
Build our RT-SDK Makefiles
We can now use the previously downloaded cmake to create our Linux Makefiles for the RT-SDK (cmake v3.14 or higher) — which I will do in a sub-directory of my home directory.
# change to home directory
cd ~# create a directory for our makefiles
mkdir rtbuild
cd rtbuild# create a subdirectory for external XML library
mkdir -p external/dlcache
cp /opt/libxml2-2.9.9.tar.gz external/dlcache# add cmake to PATH
export PATH=/opt/cmake-3.21.0-linux-x86_64/bin:$PATH#build the makefiles - see documentation for list of parameters
cmake ../Real-Time-SDK -DBUILD_UNIT_TESTS=OFF
Build an example and run it
Once we have our makefiles, we can then build one of the examples and run it
# build Consumer example 100
make Cons100# LD_LIBRARY_PATH = directories where executables search for shared libraries
export LD_LIBRARY_PATH=~/rtbuild/install/lib64# change to executables directory and run example 100
cd ~/Real-Time-SDK/Cpp-C/Ema/Executables/LIN5_64_GCC1121/Optimized/
./Cons100
Editing the Linux source in VS Code
Once I had an example running, the next step was to modify the code e.g. to test out a customer scenario.
As mentioned above, previously I would edit the code in Windows and then copy the file across to the relevant Linux directory before running the make command again.
However, once I discovered the Remote — WSL extension for VS Code, my workflow became much smoother.
There are a couple of different ways of utilising the VS Code WSL integration.
Invoke VS Code from WSL Terminal
If you already have a WSL Terminal then you could invoke VS Code from the command line by typing code . from the directory where your source code is.
Which should present Visual Studio code with the WSL directory opened up for you.
Note below the WSL Distro name is shown in the bottom left corner and the title bar makes it clear you are editing a WSL file (as opposed to a local one)
If however, you don’t have a WSL terminal open and perhaps you are already in VS Code or you just want to go straight to editing a source file, you can invoke WSL from VS Code.
Invoking WSL from VS Code
Click the WSL button in the bottom left-hand corner and choose the appropriate choice from the drop-down list presented by VS Code.
For example, if you only have one WSL distro installed or you want to use your default distro, you can just select New WSL Window.
If you have multiple distros, then you can select New WSL Window Using Distro… and choose the required Distro you wish to work with.
You can change the default WSL distro by opening a windows CMD prompt or Powershell and executing wslconfig /l to list your distros and then wslconfig /s <distroname> to change your default.
Building and Executing code direct from VS Code
Once you have made your code changes, you can build and execute the application from within VS Code by opening a Terminal inside VS Code and executing your make and run commands within the terminal.
I personally prefer to have two terminals open — one in the makefile folder (e.g my rtbuild in this instance) and one in the executables folder — so I can easily make changes, build and execute. Note the two bash icons on the right-hand side — which you can use to flick between the terminals.
As you can see, the WSL + VS Code Remote extension certainly makes it easier to code, edit and run C++ Linux applications on a Windows device.
As a next step, I plan to explore the newer features of Visual Studio 2019 and 2022 — which promise to provide an even simpler workflow. I will hopefully report back my findings here or in another article.
Setting up a basic Java development environment on WSL?
Given that Java is designed to be ‘Write Once, Run Everywhere” I should NOT really need to set up a Java Linux dev environment on WSL.
However, for me, I just wanted to have the option to test the Java version of our RT-SDK on Linux. I recall several years ago, there was an incident with one of our older Java APIs where the customer issue could only be recreated on a Linux environment. I have never come across this with our newer RT-SDK — nevertheless, I felt it was better to be prepared — just in case.
Building and running a Java example on my Fedora Remix WSL
Very little action was required in order to run one of the RT-SDK Java examples on my WSL.
I just did a search to see what packages were available, picked a version compatible with our RT-SDK and installed it.
# get a list of available Java packages
sudo dnf search openjdk# install a compatible development package
sudo dnf install java-11-openjdk-devel# build and run an RT-SDK example
cd ~/Real-Time-SDK/Java/# build the jar files (a once off)
./gradlew jar# Run consumer example 100
./gradlew runconsumer100
As per before, I can also edit the code and run the example from VS Code as required.
Summary
As a Windows developer having to code & test under Linux, the combination of Windows Subsystem for Linux and Visual Studio Code really has made life simpler for me. I can do most of my work in my comfort zone of Windows and still easily recreate customer’s Linux specific scenarios and test Linux versions of our examples with a minimum of effort.
I hope you found my experience useful and are able to apply some of the above in your own developer workflows.
Some of the key links referenced in the article:
- VS Code Remote — WSL extension (part of the Remote Development extension pack)
- Microsoft blog post: Visual Studio 2019 version 16.1 added native support for using C++ with WSL
- Microsoft blog post: Visual Studio 2022 introduces an improved WSL 2 toolset for C++ development
- Microsoft Guide to Installing WSL on Windows 10 | Microsoft Docs
- Fedora Remix WSL from the Microsoft Store or GitHub
- Our Refinitiv/Real-Time-SDK on github.com