Linux Development with C++ in Visual Studio 2019: WSL, ASan for Linux, Separation of Build and Debug

Erika Sweet

Erika

In Visual Studio 2019 you can target both Windows and Linux from the comfort of a single IDE. In Visual Studio 2019 version 16.1 Preview 3 we announced several new features specific to the Linux Workload: native support for the Windows Subsystem for Linux (WSL), AddressSanitizer integration, and the ability to separate build and debug targets. If you’re just getting started with cross-platform development, I recommend trying our native support for WSL.

Native support for the Windows Subsystem for Linux (WSL)

Visual Studio now provides native support for using C++ with WSL. WSL lets you run a lightweight Linux environment directly on Windows, including most command-line tools, utilities, and applications. In Visual Studio you no longer need to add a remote connection or configure SSH in order to build and debug on your local WSL installation. Check out our post on native support for WSL in Visual Studio to learn more and follow a step-by-step guide on getting started.

AddressSanitizer for the Linux Workload

In Visual Studio 2019 version 16.1 Preview 3 we have integrated AddressSanitizer (ASan) into Visual Studio for Linux projects. ASan is a runtime memory error detector for C/C++. You can enable ASan for MSBuild-based Linux projects and CMake projects that target a remote Linux machine or WSL. Check out our post on AddressSanitizer for the Linux Workload in Visual Studio for more information.

Separate build and debug targets for Linux projects

You can now separate your remote build machine from your remote debug machine for both MSBuild-based Linux projects and CMake projects that target a remote Linux machine. For example, you can now cross-compile on x64 and deploy to an ARM device when targeting IoT scenarios.

For a MSBuild-based Linux project, you can specify a new remote debug machine in the project’s Property Pages (Configuration Properties > Debugging > Remote Debug Machine). By default, this value is synchronized with your remote build machine (Configuration Properties > General > Remote Build Machine).

The drop-down menu is populated with all established remote connections. To add a new remote connection, navigate to Tools > Options > Cross Platform > Connection Manager or search for “Connection Manager” in the search bar at the top of your screen. You can also specify a new remote deploy directory in the project’s Property Pages (Configuration Properties > General > Remote Deploy Directory).

By default, only the files necessary for the process to debug will be deployed to the remote debug machine. You can view/configure which source files will be deployed via the Solution Explorer. When you click on a source file, you will see a preview of its File Properties directly below the Solution Explorer. You can also right-click on a source file and select “Properties.”

The “Content” property specifies whether the file will be deployed to the remote debug machine. You can also disable deployment entirely by navigating to Property Pages > Configuration Manager and unchecking “Deploy” for the desired configuration.

If you want complete control over your project’s deployment (e.g. some files you want to deploy are outside of your solution or you want to customize your remote deploy directory per file/directory), then you can append the following code block(s) to your .vcxproj file:

For CMake projects that target a remote Linux machine, you can specify a new remote debug machine via launch.vs.json. By default, the value of “remoteMachineName” will be synchronized with the “remoteMachineName” property in CMakeSettings.json, which corresponds to your remote build machine. These properties no longer need to match, and the value of “remoteMachineName” in launch.vs.json will dictate the remote machine used for deploy and debug.

IntelliSense will suggest all a list of all established remote connections, but you can add a new remote connection by navigating to Tools > Options > Cross Platform > Connection Manager or searching for “Connection Manager” in the search bar at the top of your screen.

If you want complete control over your deployment, you can append the following code block(s) to launch.vs.json:

Resolved issues

The best way to report a problem or suggest a feature to the C++ team is via Developer Community. The following feedback tickets related to C++ cross-platform development have been recently resolved in Visual Studio 2019 16.1 Preview 2 or Preview 3:

No configurations when using CppProperties.json

Unable to attach process of linux vm

cmake linux binary deployment fails with WSL

Infobar appears when open existing CMake cache fails

VS2017 crashes if SSH has connection error while building remote Linux CMake project

CTest timeout feature doesn’t work in test explorer

CMake: Any minor change to CMakeLists.txt triggers a full cache regeneration

CMake + Intellisense: Preprocessor definitions in CMakeLists do not work with quoted strings

Intellisense problem for Linux Makefile project

Talk to us!

Do you have feedback on our Linux tooling in Visual Studio? Pick a time to chat with the C++ cross-platform team and share your experiences – the good and the bad – to help us prioritize and build the right features for you! We can also be reached via the comments below, email (visualcpp@microsoft.com), and Twitter (@VisualC) and (@erikasweet_).

Erika Sweet
Erika Sweet

Follow Erika   

8 Comments
Avatar
Ron Even 2019-05-25 16:18:19
That is an absolutely great feature my team wanted for a very long time, however, I can't make it copy the build output file to the remote debugging machine. My output file is obviously not a file in my project, so I can't set it to content. When I set one of my project files Content to True, it is copied. I guess customly specifying the output file in the vcxproj will work, but I am probably missing something here... Also, I tried changing the MSBuild logging level but deployment part always shows: 2>Connecting to remote systems.2>Resolving remote paths.2>Copying files.2>Deployment took 1.6778987 seconds. So I can't know what's wrong
Avatar
Ron Even 2019-05-25 16:35:10
That is an absolutely great feature my team wanted for a very long time, however, I can't make it copy the build output file to the remote debugging machine. My output file is obviously not a file in my project, so I can't set it to content. When I set one of my project files Content to True, it is copied. I guess customly specifying the output file in the vcxproj will work, but I am probably missing something here... Also, I tried changing the MSBuild logging level but deployment part always shows: 2>Connecting to remote systems. 2>Resolving remote paths. 2>Copying files. 2>Deployment took 1.6778987 seconds. So I can't know what's wrong
Avatar
Jack Hansen 2019-06-04 01:00:15
I tried to download this and after a little while found a forum saying preview 3 is not available in community edition. This could be made clear in the writeup and save some folks time, if it's true. Anyway, the feature set looks like something I'd like to try.
André Nicolaysen
André Nicolaysen 2019-06-07 15:58:13
Is it possible to get more information about how to set up cmake to have another debug target?  I'd like to develop with Visual Studio, build on WSL for Linux ARM and then deploy and debug on Linux ARM. It seems that this should be possible, but I can't seem to wrap my head arround how cmake / visual studio should be configured. Any help or guidance is greatly appreciated.
Avatar
Office Browser Sync 2019-06-15 13:15:43
Hi Erika, I understand that the documentation is still in-progress, but I wanted to know if this configuration is supported: 1) Build in Linux-Machine-A (x64) 2) Transfer the executable from Linux-Machine-A to Linux-Machine-B (ARM, gdbserver-only). -->  Currently, I don't see a method to do this, other than to write a script and SSH into A to make the transfer. 3) Debug on B. --> It seems like gdb needs to be in Windows.  However, my entire toolchain is in Linux, and machine B only has gdbserver.  I was hoping VS could start gdb on A to attach to the process in B, and relay the data.  It seems like `miDebuggerPath` is only looking in Windows. It's fine it this configuration is not supported -- I just need to know so I can move on. Thanks, Erika.
Avatar
Paul Lauzon 2019-07-04 16:13:33
Thanks for the article!   Is it possible to build (cross-compile) a linux executable on Windows using Clang/LLVM and then copy the executable to a remote Linux machine for running and debugging?  I tried creating a few projects using VisualStudio2019 without success so far.  When selecting a Linux target, it automatically tries to compile on the Linux target.  When selecting a Windows target, it uses the Windows source headers (win32) even when I force it to use Clang/LLVM in a CMakeSettings.json.  Perhaps there is a way to do this?