{"id":23868,"date":"2018-11-26T20:44:34","date_gmt":"2018-11-26T20:44:34","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=23868"},"modified":"2022-08-11T17:30:57","modified_gmt":"2022-08-11T17:30:57","slug":"using-visual-studio-for-cross-platform-c-development-targeting-windows-and-linux","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/using-visual-studio-for-cross-platform-c-development-targeting-windows-and-linux\/","title":{"rendered":"Using Visual Studio for Cross Platform C++ Development Targeting Windows and Linux"},"content":{"rendered":"<p><div class=\"alert alert-info\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Content outdated<\/strong><\/p> For up-to-date documentation see <a class=\"Hyperlink SCXW225916456 BCX8\" href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/get-started-linux-cmake?view=msvc-170\" target=\"_blank\" rel=\"noreferrer noopener\"><span class=\"TextRun Underlined SCXW225916456 BCX8\" lang=\"EN-GB\" xml:lang=\"EN-GB\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW225916456 BCX8\" data-ccp-charstyle=\"Hyperlink\">Create C++ cross-platform projects in Visual Studio<\/span><\/span><\/a>.<\/div>A great strength of C++ is the ability to target multiple platforms without sacrificing performance. If you are using the same codebase for multiple targets, then <a href=\"https:\/\/aka.ms\/cmake\">CMake<\/a> is the most common solution for building your software. You can use Visual Studio for your C++ cross platform development when using CMake without needing to create or generate Visual Studio projects. Just open the folder with your sources in Visual Studio (File &gt; <a href=\"https:\/\/aka.ms\/openfolder\/cpp\">Open Folder<\/a>). Visual Studio will recognize CMake is being used, then use metadata CMake produces to configure IntelliSense and builds automatically. You can quickly be editing, building and debugging your code locally on Windows, and then switching your configuration to do the same on Linux all from within Visual Studio.<\/p>\n<p>Teams working on these types of code bases may have developers who have different primary operating systems, e.g. some people are on Linux (and may be using the <a href=\"https:\/\/code.visualstudio.com\/docs\/languages\/cpp\">Visual Studio Code<\/a> editor) and some are on Windows (probably using the Visual Studio IDE). In an environment like this, the choice of tools may be up to the developers themselves. You can use Visual Studio in an environment like this without perturbing your other team members or making changes to your source as is. If or when additional configuration is needed it is <a href=\"https:\/\/aka.ms\/openfolder\/cpp\">saved in flat json files<\/a> that can be saved locally, or shared in source control with other developers using Visual Studio without impacting developers that are not using it.<\/p>\n<p>Visual Studio isn\u2019t just for Windows C and C++ development anymore. If you follow the tutorial below on your own machine, you will clone an open source project from GitHub, open it in Visual Studio, edit, build and debug on Windows with no changes to the project. Then Visual Studio will add a connection to a Linux machine and edit, build and debug it on that remote machine.<\/p>\n<p>The next section shows you how to setup Visual Studio, followed by a section on how to configure your Linux target, and last the tutorial itself \u2013 have fun!<\/p>\n<h2>Setting up Visual Studio for Cross Platform C++ Development<\/h2>\n<p>First you need to have Visual Studio installed. If you have it installed already confirm that you have the <strong>Desktop development with C++<\/strong> and <strong>Linux development with C++<\/strong> workloads installed. If you don\u2019t have Visual Studio installed <a href=\"https:\/\/aka.ms\/vsinstallcpplinux\">use this link<\/a> to install it with the minimal set of components for this tutorial selected. This minimal install is only a 3GB, depending on your download speed installation should not take more than 10 minutes.<\/p>\n<p>Once that is done you are ready to go on Windows.<\/p>\n<h2>Configuring your Linux machine for cross platform C++ development<\/h2>\n<p>Visual Studio does not have a requirement for a specific distribution of Linux; use any you would like to. That can be on a physical machine, in a VM, the cloud, or even running on Windows Subsystem for Linux. The tools Visual Studio requires to be present on the Linux machine are: C++ compilers, GDB, ssh, and zip. On Debian based systems you can install these dependencies as follows.<\/p>\n<pre>sudo apt install -y openssh-server build-essential gdb zip<\/pre>\n<p>Visual Studio also of course requires CMake. However, it needs a recent version of CMake that has server mode enabled (at least 3.8). Our team produces a universal build of CMake that you can install on any Linux distro. We recommend using this build over what may be in your package manager as it is built from our fork of the CMake source. Using that fork ensures that you have the latest features in case they haven\u2019t made it back up stream. We document <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/linux\/cmake-linux-project\">how to configure CMake here<\/a>, and you can <a href=\"https:\/\/github.com\/Microsoft\/CMake\/releases\">get the CMake binaries from here<\/a>. Go to that page and download the version that matches your system architecture on your Linux machine. Mark it as an executable:<\/p>\n<pre>wget chmod +x cmake-3.11.18033000-MSVC_2-Linux-x86_64.sh\r\nchmod +x cmake-3.11.18033000-MSVC_2-Linux-x86_64.sh\r\n<\/pre>\n<p>You can see the options for running it with &#8211;help. We recommend that you use the &#8211;prefix option to specify installing in the \/usr\/local path as that is the default location Visual Studio looks for CMake at.<\/p>\n<pre>sudo .\/cmake-3.11.18033000-MSVC_2-Linux-x86_64.sh --skip-license --prefix=\/usr\/local<\/pre>\n<h2>Tutorial: Using the Bullet Physics SDK GitHub repo in Visual Studio<\/h2>\n<p>Now that you have Visual Studio and a Linux machine ready to go lets walk through getting a real open source C++ project working in Visual Studio targeting Windows and Linux. For this tutorial we are going to use <a href=\"https:\/\/github.com\/bulletphysics\/bullet3\">the Bullet Physics SDK on GitHub<\/a>. This is a library that provides collision detection and physics simulations for a variety of different applications. There are sample executable programs within it to use so we have something to interact with without having to write additional code. You will not have to modify any of this source or build scripts in the steps that follow.<\/p>\n<p>Note that you can use any Linux distro for this tutorial, however using Windows Subsystem for Linux for this one is not a good idea since the executable we are going to run is graphical which is not supported officially there.<\/p>\n<h3>Step 1 \u2013 Clone and open the bullet3 repo<\/h3>\n<p>To start, clone the bullet3 repository from GitHub on the machine where you have Visual Studio installed. If you have git installed on your command line it will be as simple as running git clone wherever you would like to keep this repository.<\/p>\n<pre>git clone https:\/\/github.com\/bulletphysics\/bullet3.git<\/pre>\n<p>Now open the root project folder, bullet3, that was created by cloning the repo in Visual Studio. Use the menu option File &gt; Open &gt; Folder which will detect and use the CMakeLists.txt file or you can use File &gt; Open &gt; CMake to select the desired CMakeLists.txt file directly.<\/p>\n<p>You can also clone a git repo directly within Visual Studio which will automatically open the folder when you are done.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23869\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat1.png\" alt=\"Visual Studio menu for File &gt; Open &gt; CMake\" width=\"970\" height=\"591\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat1.png 970w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat1-300x183.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat1-768x468.png 768w\" sizes=\"(max-width: 970px) 100vw, 970px\" \/><\/p>\n<p>As soon as you open the folder your folder structure will be visible in the Solution Explorer.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23870\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat2.png\" alt=\"\" width=\"544\" height=\"1091\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat2.png 544w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat2-150x300.png 150w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat2-511x1024.png 511w\" sizes=\"(max-width: 544px) 100vw, 544px\" \/><\/p>\n<p>This view shows you exactly what is on disk, not a logical or filtered view. By default, it does not show hidden files. To see them, select the show all files button in the Solution Explorer.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23871\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat3.png\" alt=\"\" width=\"536\" height=\"168\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat3.png 536w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat3-300x94.png 300w\" sizes=\"(max-width: 536px) 100vw, 536px\" \/><\/p>\n<h3>Step 2 \u2013 Use targets view<\/h3>\n<p>When you open a folder that uses CMake, Visual Studio will automatically generate the CMake cache. This will take a few moments, or longer depending on the size of your project. The status of this process is placed in the output window. It is complete when you see the message \u201cTarget info extraction done\u201d.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-23872 size-full\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat4.png\" alt=\"Visual Studio Output window showing output from CMake\" width=\"710\" height=\"373\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat4.png 710w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat4-300x158.png 300w\" sizes=\"(max-width: 710px) 100vw, 710px\" \/><\/p>\n<p>After this completes, IntelliSense is configured, the project can build, and you can launch the application and debug it. Visual Studio also now understands the build targets that the CMake project produces. This enables an alternate CMake Targets View that provides a logical view of the solution. Use the Solutions and Folders button in the Solution Explorer to switch to this view.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23873\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat5.png\" alt=\"\" width=\"774\" height=\"167\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat5.png 774w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat5-300x65.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat5-768x166.png 768w\" sizes=\"(max-width: 774px) 100vw, 774px\" \/><\/p>\n<p>Here is what that view looks like for the Bullet SDK.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23874\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat6.png\" alt=\"Solution Explorer CMake targets view\" width=\"534\" height=\"1248\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat6.png 534w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat6-128x300.png 128w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat6-438x1024.png 438w\" sizes=\"(max-width: 534px) 100vw, 534px\" \/><\/p>\n<p>This gives us a more intuitive view of what is in this source base. You can see some targets are libraries and others are executables. You can expand these nodes and see the source that comprises them independent of how it is represented on disk.<\/p>\n<h3>Step 3 &#8211; Set breakpoint, build and run<\/h3>\n<p>For this tutorial, use an executable to get something that can just run and get into the debugger. Select AppBasicExampleGui and expand it. Open the file BasicExample.cpp. This is an example program that demonstrates the Bullet Physics library by rendering a bunch of cubes arranged as a single block that are falling and smash apart on hitting a surface.\u00a0 Next set a break point that will be triggered when you click in the running application. That is handled in a method within a helper class used by this application. To quickly get there select CommonRigidBodyBase that the struct BasicExample is derived from around line 30. Right click and choose Go to Definition. Now you are in the header CommonRigidBodyBase.h. In the browser view above your source you should see that you are in the CommonRigidBodyBase. To the right you can select members within to examine, drop that selection down and select mouseButtonCallbackwhich will take you to the definition of that function in the header.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23875\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat7.png\" alt=\"Visual Studio member list toolbar\" width=\"871\" height=\"53\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat7.png 871w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat7-300x18.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat7-768x47.png 768w\" sizes=\"(max-width: 871px) 100vw, 871px\" \/><\/p>\n<p>Place a breakpoint on the first line within this function. This will trigger when you click a mouse button within the window of the application when launched under the Visual Studio debugger.<\/p>\n<p>To launch the application, select the launch dropdown with the play icon that says \u201cSelect Startup Item\u201d in the toolbar.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23876\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat8.png\" alt=\"Visual Studio toolbar launch drop down for Select Startup Item\" width=\"370\" height=\"35\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat8.png 370w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat8-300x28.png 300w\" sizes=\"(max-width: 370px) 100vw, 370px\" \/><\/p>\n<p>In the dropdown select AppBasicExampleGui.exe. Now press the launch button. This will cause the project to build our application and necessary dependencies, then launch it with the Visual Studio debugger attached. It will take a few moments while this process starts, then the application will appear.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23877\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat9.png\" alt=\"Visual Studio debugging a Windows application\" width=\"1444\" height=\"812\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat9.png 1444w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat9-300x169.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat9-768x432.png 768w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat9-1024x576.png 1024w\" sizes=\"(max-width: 1444px) 100vw, 1444px\" \/><\/p>\n<p>Move your mouse into the application window, click a button, and the breakpoint will be triggered. This pause execution of your program, bring Visual Studio back to the foreground, and you will be at your breakpoint. You will be able to inspect the application variables, objects, threads, memory, and step through your code interactively using Visual Studio. You can click continue to let the application resume and exit it normally or cease execution within Visual Studio using the stop button.<\/p>\n<p>What you have seen so far is by simply cloning a C++ repo from GitHub you can open the folder with Visual Studio and get an experience that provides IntelliSense, a file view, a logical view based on the build targets, source navigation, build, and debugging with no special configuration or Visual Studio specific project files. If you were to make changes to the source you would get a diff view from the upstream project, make commits, and push them back without leaving Visual Studio. There\u2019s more though. Let\u2019s use this project with Linux.<\/p>\n<h3>Step 4 \u2013 Add a Linux configuration<\/h3>\n<p>So far, you have been using the default x64-Debug configuration for our CMake project. Configurations are how Visual Studio understands what platform target it is going to use for CMake. The default configuration is not represented on disk. When you explicitly add a configuration a file CMakeSettings.json is created that has parameters Visual Studio uses to control how CMake is run, as well as when it is run on a remote target like Linux. To add a new configuration, select the Configuration drop down in the toolbar and select \u201cManage Configurations\u2026\u201d<\/p>\n<p>The Add Configuration to CMakeSettings dialog will appear.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23878\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat10.png\" alt=\"Add Configuration to CMakeSettings dialog\" width=\"438\" height=\"543\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat10.png 438w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat10-242x300.png 242w\" sizes=\"(max-width: 438px) 100vw, 438px\" \/><\/p>\n<p>Here you see Visual Studio has preconfigured options for many of the platforms Visual Studio can be configured to use with CMake. If you want to continue to use the default x64-Debug configuration that should be the first one you add. You want that for this tutorial so can switch back and forth between Windows and Linux configurations. Select x64-Debug and click Select. This creates the CMakeSettings.json file with a configuration for \u201cx64-Debug\u201d and switches Visual Studio to use that configuration instead of the default. This happens very quickly as the provided settings are the same as the default. You will see the configuration drop down no longer says \u201c(default)\u201d as part of the name.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23879\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat11.png\" alt=\"Launch drop down configured for X64-Debug\" width=\"217\" height=\"41\" \/><\/p>\n<p>You can use whatever names you like for your configurations by changing the name parameter in the CMakeSettings.json.<\/p>\n<p>Now that you have a configuration specified in the configuration dropdown Manage Configurations option opens the CMakeSettings.json file so you can adjust values there. To add a Linux configuration right click the CMakeSettings.json file in the solution explorer view and select Add Configuration.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-23880 size-full\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat12.png\" alt=\"CMakeSettings.json context menu for Add Configuration\" width=\"578\" height=\"385\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat12.png 578w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat12-300x200.png 300w\" sizes=\"(max-width: 578px) 100vw, 578px\" \/><\/p>\n<p>This provides the same Add Configuration to CMakeSettings dialog you saw before. This time select Linux-Debug, then save the CMakeSettings.json file. Now in the configuration drop down select Linux-Debug.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23881\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat13.png\" alt=\"Launch configuration drop down with X64-Debug and Linux-Debug options\" width=\"207\" height=\"90\" \/><\/p>\n<p>Since this is the first time you are connecting to a Linux system the Connect to Remote System dialog will appear.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23883\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat14.png\" alt=\"Visual Studio Connect to Remote System dialog\" width=\"456\" height=\"430\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat14.png 456w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat14-300x283.png 300w\" sizes=\"(max-width: 456px) 100vw, 456px\" \/><\/p>\n<p>Provide the connection information to your Linux machine and click Connect. This will add that machine as your default remote machine which is what the CMakeSetttings.json for Linux-Debug is configured to use. It will also pull down the headers from your remote machine so that you get IntelliSense specific to that machine when you use it. Now Visual Studio will send your files to the remote machine, then generate the CMake cache there, and when that is done Visual Studio will be configured for using the same source base with that remote Linux machine. These steps may take some time depending on the speed of your network and power of your remote machine. You will know this is complete when the message \u201cTarget info extraction done\u201d appears in the CMake output window.<\/p>\n<h3>Step 5 &#8211; Set breakpoint, build and run on Linux<\/h3>\n<p>Since this is a desktop application you need to provide some additional configuration information to the debug configuration. In the CMake Targets view right click AppBasicExampleGui and choose <em>Debug and Launch<\/em> settings.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-23884 size-full\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat15.png\" alt=\"Debug and Launch Settings context menu\" width=\"355\" height=\"304\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat15.png 355w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat15-300x257.png 300w\" sizes=\"(max-width: 355px) 100vw, 355px\" \/><\/p>\n<p>This will open a file launch.vs.json that is in the hidden .vs subfolder. This file is local to your development environment. You can move it into the root of your project if you wish to check it in and save it with your team. In this file a configuration has been added for AppBasicExampleGui. These default settings work in most cases, as this is a desktop application you need to provide some additional information to launch the program in a way you can see it on our Linux machine. You need to know the value of the environment variable DISPLAY on your Linux machine, run this command to get it.<\/p>\n<pre>echo $DISPLAY<\/pre>\n<p>In my case this was :1. In the configuration for AppBasicExampleGui there is a parameter array \u201cpipeArgs\u201d. Within there is a line \u201c${debuggerCommand}\u201d. This is the command that launches gdb on the remote machine. Visual Studio needs to export the display into this context before that command runs. Do so by modifying that line as follows using the value of your display.<\/p>\n<pre>\"export DISPLAY=:1;${debuggerCommand}\",<\/pre>\n<p>Now in order to launch and debug our application, choose the \u201cSelect Startup Item\u201d dropdown in the toolbar and choose AppBasicExampleGui.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23885\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat16.png\" alt=\"Select Startup Item drop down options\" width=\"674\" height=\"521\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat16.png 674w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat16-300x232.png 300w\" sizes=\"(max-width: 674px) 100vw, 674px\" \/><\/p>\n<p>Now press that button or hit F5. This will build the application and its dependencies on the remote Linux machine then launch it with the Visual Studio debugger attached. On your remote Linux machine, you should see an application window appear with the same falling bunch of cubes arranged as a single block.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23886\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat17.png\" alt=\"Linux application launched from Visual Studio\" width=\"1149\" height=\"864\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat17.png 1149w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat17-300x226.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat17-768x578.png 768w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat17-1024x770.png 1024w\" sizes=\"(max-width: 1149px) 100vw, 1149px\" \/><\/p>\n<p>Move your mouse into the application window, click a button, and the breakpoint will be triggered. This pause execution of your program, bring Visual Studio back to the foreground, and you will be at your breakpoint. You should also see a Linux Console Window appear in Visual Studio. This window provides output from the remote Linux machine, and it can also accept input for stdin. It can of course be docked where you prefer to see it and it\u2019s position will be used again in future sessions.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23887\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat18.png\" alt=\"\" width=\"505\" height=\"293\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat18.png 505w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat18-300x174.png 300w\" sizes=\"(max-width: 505px) 100vw, 505px\" \/><\/p>\n<p>You will be able to inspect the application variables, objects, threads, memory, and step through your code interactively using Visual Studio. This time on a remote Linux machine instead of your local Windows environment. You can click continue to let the application resume and exit it normally or cease execution within Visual Studio using the stop button. All the same things you\u2019d expect if this were running locally.<\/p>\n<p>Look at the Call Stack window and you will see this time the Calls to x11OpenGLWindow since Visual Studio has launched the application on Linux.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-23888\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat19.png\" alt=\"\" width=\"506\" height=\"298\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat19.png 506w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2019\/02\/xplat19-300x177.png 300w\" sizes=\"(max-width: 506px) 100vw, 506px\" \/><\/p>\n<h2>What you learned and where to learn more<\/h2>\n<p>So now you have seen the same code base, cloned directly from GitHub, build, run, and debugged on Windows with no modifications. Then with some minor configuration settings build, run and debugged on a remote Linux machine as well. If you are doing cross platform development, we hope you find a lot to love here. Visual Studio C and C++ development is not just for Windows anymore.<\/p>\n<p><strong>Further articles<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/linux-development-with-c-in-visual-studio\/\">Original Linux C++ announcement post<\/a>, this goes into depth on Linux C++ projects that use msbuild to drive remote compilation.<\/li>\n<\/ul>\n<p><strong>Documentation links<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/ide\/cmake-tools-for-visual-cpp?view=vs-2017\">CMake projects<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/ide\/non-msbuild-projects?view=vs-2017\">Open folder projects<\/a> for C++ for any build system<\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/linux\/download-install-and-setup-the-linux-development-workload?view=vs-2017\">Download and setup the Linux workload<\/a>, the root page for Visual Studio C++ Linux documentation<\/li>\n<\/ul>\n<p>This section will be updated in the future with links to new articles on Cross Platform Development with Visual Studio.<\/p>\n<h2>Give us feedback<\/h2>\n<p><a href=\"https:\/\/aka.ms\/vsinstallcpplinux\">Use this link to download Visual Studio 2017<\/a> with everything you need to try the steps in this tutorial, then try it with your projects.<\/p>\n<p>Your feedback is very important to us. We look forward to hearing from you and seeing the things you make.<\/p>\n<p>As always, we welcome your feedback. We can be reached via the comments below or via email (<a href=\"mailto:visualcpp@microsoft.com\">visualcpp@microsoft.com<\/a>).\u00a0If you encounter other problems with MSVC or have a suggestion for Visual Studio please let us know through\u00a0<a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/ide\/how-to-report-a-problem-with-visual-studio-2017?view=vs-2017\">Help &gt; Send Feedback &gt; Report A Problem \/ Provide a Suggestion in the product<\/a>, or\u00a0via\u00a0<a href=\"https:\/\/developercommunity.visualstudio.com\/topics\/C%2B%2B.html\">Developer Community<\/a>.\u00a0You can also find us on Twitter (<a href=\"https:\/\/twitter.com\/visualc\">@VisualC<\/a>).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A great strength of C++ is the ability to target multiple platforms without sacrificing performance. If you are using the same codebase for multiple targets, then CMake is the most common solution for building your software. You can use Visual Studio for your C++ cross platform development when using CMake without needing to create or [&hellip;]<\/p>\n","protected":false},"author":677,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[216],"tags":[],"class_list":["post-23868","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-documentation"],"acf":[],"blog_post_summary":"<p>A great strength of C++ is the ability to target multiple platforms without sacrificing performance. If you are using the same codebase for multiple targets, then CMake is the most common solution for building your software. You can use Visual Studio for your C++ cross platform development when using CMake without needing to create or [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/23868","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/677"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=23868"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/23868\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=23868"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=23868"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=23868"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}