C++ Linux development with Visual Studio: incremental build improvements and expanded shell support
Visual Studio 2019 allows C++ developers to target both Windows and Linux (including the Windows Subsystem for Linux) from the comfort of a single IDE. Visual Studio 2019 version 16.7 Preview 3 introduces two features specific to Linux development: improved build incrementality for MSBuild-based Linux projects, and support for a wider range of Linux distributions and shells.
There are two ways C++ developers can target Linux systems from Visual Studio. Our recommendation for anything cross-platform or with an eye to open-sourcing is our native support for CMake. This allows you to leverage the same source code and build scripts to target multiple platforms. Alternatively, you can create a MSBuild-based Linux project for a familiar Visual Studio experience.
Improved build incrementality for MSBuild-based Linux projects
You can now leverage Ninja for faster incremental builds in MSBuild-based Linux projects. To enable building with Ninja, navigate to Property Pages > General and set “Enable Incremental Build” to “With Ninja”.
Make sure you have ninja installed on your Linux system. You can install ninja on Debian-based Linux systems with the following commands:
sudo apt-get update sudo apt-get install ninja-build
We tested Ninja’s build performance with a MSBuild-based Linux project that contained 1000 .h files and 1000 .cpp files. Ninja led to faster build times for both a full rebuild and a build where one header file was changed.
|End to end build time for full rebuild (in min)||End to end build time with one change (in min)|
|Enable Incremental Build == With Ninja||8:01||0:32|
|Enable Incremental Build == No||12:57||5:26|
These tests were run against a local VM (Ubuntu 20.04) connected to Visual Studio over SSH, but you can leverage these improvements with both our SSH support and native support for WSL. As a reminder, in MSBuild-based Linux projects you can select your platform toolset (WSL or remote) via Property Pages > General > Platform Toolset.
Support for a wider range of Linux distributions and shells
We also added support for a wider range of Linux distributions and shells. These changes apply to both CMake projects and MSBuild-based Linux projects targeting a remote Linux system or WSL. Visual Studio now queries for the shell the first time a command is issued. It then decides how to format a command line when redirecting stderr and how to detach from a running command based on the shell that is discovered. Visual Studio now supports the following shells: sh, csh, bash, tcsh, ksh, zsh, and dash. If the shell found on the Linux system is not supported, then we fall back to explicitly use “sh” for all commands.
We also added new options and commands to ConnectionManager.exe to help you override the choice of shell for a connection. ConnectionManager.exe is a command-line utility to manage stored remote connections outside of Visual Studio.
- ConnectionManager.exe list – -properties
- When present, the list of properties defined for the connection will be printed out for each connection.
- ConnectionManager.exe modify [default | connection_id | user@host [- -port port]] – -property [key=value]
- Define or modify a property on a connection. If “value” is empty, then the property “key” is deleted. For example, use ConnectionManager.exe modify 21212121 – -property shell=csh to override the choice of shell for the connection with connection ID 21212121.
- You can run the command ConnectionManager.exe list to view a list of stored connections by connection ID.
Finally, we’ve tested our support against a wider range of Linux distros through changes to the commands issued. Key functionality like project creation, the remote header sync, build, and debug have been tested for both CMake projects and MSBuild-based Linux projects with the following distros + shells.
|Unix distro||Validated shells|
|FreeBSD||csh, fish, zsh, bash|
|Ubuntu 18.04||fish, bash, csh, zsh|
Give us your feedback
Download Visual Studio 2019 version 16.7 Preview 3 today and give it a try. We’d love to hear from you to help us prioritize and build the right features for you. We can be reached via the comments below, Developer Community, and Twitter (@VisualC). The best way to file a bug or suggest a feature is via Developer Community.
I once used both VS Linux remote and VSCode SSH. For myself, I feel VSCode SSH is more lightweight and agile. The main issue I had when using VS Linux remote, everytime I changed some code and did build/debug, it need to rsync files to the target Linux machine and these usually took some time even if there were only few files changing. It was really not a good experience and the development procedure was stumbling. So after a period of trying, most of the team members returned back to Hyper-V virtual desktop rather than remote development, until we found VSCode SSH. Hope the new version would improve this.
Thanks for the feedback! We addressed this issue in version 16.5 Preview 2. Visual Studio now keeps a “fingerprint file” of the last set of sources copied remotely and optimizes behavior based on the number of files that have changed.
1. If no changes are identified, then no copy occurs.
2. If only a few files have changed, then sftp is used to copy the files individually.
3. If only a few directories have changed, then a non-recursive rsync command is issued to copy those directories.
4. Otherwise, a rsync recursive copy is called from the first common parent directory of the changed files.
More information and data on perf tests tests that we run can be found here.
This still requires running commands on an actual Linux system correct?
We’re using a Windows->Linux cross-compiler. This used to work OK with Visual Studio 2010, but became pretty much unusable in 2015.
It works pretty well with Visual Studio Code now.
Yes, the support described in this blog post runs commands on an actual Linux system (WSL or a remote system). EA uses a local cross-compiler to build and leverages our Linux support to deploy & debug on WSL. If that’s interesting you can learn more about their workflow here.
Thanks for the Article, thumbs up. Just one unrelated comment, on the table [Linux distro] v/s [ validated shells ], it does list FreeBSD as a flavor of Linux distro, which as the last time I check , it wasn’t , easy fix is to change the title for the column, to Unix distro or OS distro.
Hi Erika, thank you very much for the update. I’m really keen to take advantage of linux development with Visual Studio.
When using platform toolset WSL, using MSBuild, I am not able to observe much of a difference between doing a full rebuild with ninja vs not doing so.
With Enable Incremental Build ‘With Ninja’, my build time was 00:01:39.32
With Enable Incremental Build ‘No’, my build time was 00:01:41.16
Is there any option we need to specify to help parallelize ninja? Why might my full rebuilds barely benefit from the feature?
I have ‘Max Parallel Compilation Jobs’ set to 16 in my C/C++ settings — evaluated from $([System.Environment]::ProcessorCount)
No, there should be no other option you need to specify to parallelize ninja. We just tested on an MSBuild-based Linux project with 14 .cpp and 14.h files using the Clang for Windows Subsystem for Linux toolset and ‘Max Parallel Compilation Jobs’ set to 16 in 2019 version 16.7 Preview 5, and saw significant improvements with Ninja. Are there any other details of your project build configuration that you can share?
Ollie, the build performance is going to depend on your build system, if you change a header for example, that is included in most TUs, and they are invalidated, incrementality won’t help. Can you share a repro with us, then we can investigate.
Is there an example that could be provided showcasing cross-platform C++ unit testing? We currently utilize C++ unit test framework for our windows build and are in a need to perform the same tests on the linux cross platform build.
Hi Jared, C++ unit testing is not yet supported on Linux. Here is a suggestion on developer community that you can upvote or comment on.
Thank you for your reply. We are using MSBuild cross platform builds currently. Any updates on when or if unit test support for cross platform MSBuild based solution would be very appreciated. Thanks again!