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
Update 1/27/2020: In Visual Studio 2019 version 16.5 and later you can leverage Visual Studio’s native support for WSL when separating your build system from your remote deploy system.
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:
<ItemGroup> <RemoteDeploy Include="__example.cpp"> <!-- This is the source Linux machine, can be empty if DeploymentType is LocalRemote --> <SourceMachine>$(RemoteTarget)</SourceMachine> <TargetMachine>$(RemoteDebuggingTarget)</TargetMachine> <SourcePath>~/example.cpp</SourcePath> <TargetPath>~/example.cpp</TargetPath> <!-- DeploymentType can be LocalRemote, in which case SourceMachine will be empty and SourcePath is a local file on Windows --> <DeploymentType>RemoteRemote</DeploymentType> <!-- Indicates whether the deployment contains executables --> <Executable>true</Executable> </RemoteDeploy> </ItemGroup>
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:
"disableDeploy": false, "deployDirectory": "~\foo", "deploy" : [ { "sourceMachine": "127.0.0.1 (username=example1, port=22, authentication=Password)", "targetMachine": "192.0.0.1 (username=example2, port=22, authentication=Password)", "sourcePath": "~/example.cpp", "targetPath": "~/example.cpp", "executable": "false" } ]
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_).
Regarding Separate build and debug targets for Linux projects I’m having some issues, I’m building my project using WSL and then I want to debug / deploy to a remote machine, the build works but I have one .json file in my project that I’ve set to be content when I deploy I see this:
>Connecting to remote systems.
>CacheCleanupConnections failed
>Resolving remote paths.
>Copying files.
>Deploy failed.
I can’t find the file on my remote machine, I have setup $(RemoteDeployDir) and $(RemoteProjectDir) , can anyone help me out please?
Thanks.
OK, I’ve fixed all of my issues apart from:
>CacheCleanupConnections failed
>Resolving remote paths.
…resolving remote path takes a couple of minutes, why is that?
The feature to debug the project on a different target than it was built on is great, but it needs to be better documented and polished, otherwise you end up needing the old project structure with the makefile to copy binaries. The first problem is in the ProjectProperties->Linker->General, there are two fields named Output File now. But with a lot of experimenting I could identify each properties: The first OutputField is the relative output Path (including name + extionsion) of the linked file. This path is also used for copying to the windows project folder. On the remote target this...
thank you for the detailed feedback, we will evaluate and get back to you
Is there a way to use mutiple core to parallel compile like we do on windows? Projects are quite big and it takes a long time.
Is this for a MSBuild based Linux project, or CMake? The answer is absolutely, I’ll assume MSBuild, in Property Pages, C/C++ – General – Max Parallel Compilation Jobs
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?
this is possible to do, and we plan on documenting this scenario in the near feature, right now it would be significant to explain for MSBuild based projects, you can do it today with no problem for CMake based projects, you can use a toolset file to define the compiler, you should create a project here that looks like a Windows project
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...
Hi, first of all I apologize for the late reply. Steps (1) and (2) you can accomplish using the separation of build and deploy feature. Your “build” machine would be machine A and your “debug” machine would be machine B.
To debug on B, you can debug directly from Visual Studio without starting gdb on A. This blog post describes how to debug using gdbserver on a microcontroller using CMake.
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.
Hi André,
Unfortunately this support does not apply to native WSL configurations yet, so you will need to connect to WSL via SSH and treat it as a remote connection or order to separate your build machine (WSL) from your deploy/debug machine (ARM device). We are in the process of creating more comprehensive documentation for these new features. For now, if the steps to edit your launch.vs.json file (described above) are not working please reach out to vcpplinux-support@microsoft.com. Thank you!
Hi Erika, do you plan to support build/debug machine separation for native WSL configuration too?
Thanks!
Hi Martin, native WSL support with the separation of build and debug is now available in Visual Studio 2019 version 16.5: https://devblogs.microsoft.com/cppblog/cmake-linux-targeting-and-intellisense-improvements-in-visual-studio-2019-version-16-5-preview-2/#wsl
Yes, that is coming online in the next release 🙂
It would be a great feature that simplifies and accelerate the build process.
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.
Hi Jack,
All of these features are now available in the GA 16.1 release, available for download here.
That said, the preview channel is available for all users (Community, Professional, and Enterprise). You can install the latest preview build here. The preview channel is now on version 16.2 Preview 1.
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:Read more
2>Connecting to remote systems.
2>Resolving remote paths.
Hi Ron, I ran into the same problem but could solve it. I postet a comment here on this page how you can solve this issue.
hi, are the two machine targets having a different platform by any chance?
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...