{"id":31506,"date":"2023-01-23T19:13:44","date_gmt":"2023-01-23T19:13:44","guid":{"rendered":"https:\/\/localhost\/cppblog\/?p=31503"},"modified":"2023-01-23T19:13:44","modified_gmt":"2023-01-23T19:13:44","slug":"deploy-and-debug-apps-on-remote-targets","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/deploy-and-debug-apps-on-remote-targets\/","title":{"rendered":"Deploy and debug apps on remote targets"},"content":{"rendered":"<p>There are a number of ways that Visual Studio and Visual Studio Code enable you to interact with remote machines. Both can enable you to connect to a remote machine and use it as a build machine and debug your applications there. Sometimes though your target is not the same as your build machine. For example, for embedded Linux devices you will likely want to cross compiler the application on a more powerful build machine then deploy to the device for debugging. This post is going to demonstrate how to build an application locally in a Dev Container for either a Raspberry Pi 3 or 4, then deploy and debug the application on a Raspberry Pi. The techniques shown here will also work if the build machine is natively Linux or WSL, but to make setup easier we will use a Dev Container.<\/p>\n<h2>Raspberry Pi project<\/h2>\n<p>For this article we have prepared a simple C++ project that can run locally on Linux, on a Raspberry Pi 3 or 4.<\/p>\n<pre>git clone https:\/\/github.com\/robotdad\/raspi-cpp-devcontainer.git<\/pre>\n<p>The main.cpp simply prints the name of the host system to the output and waits a few seconds before continuing. Using CMakePresets.json we have provided a linux-debug configuration for building the app to run on the Linux host machine. There are also pi3-debug and pi4-debug configurations that use the cross compilers for those devices. The output from those configurations will only run on the Raspberry Pi they are configured for.<\/p>\n<p>To ensure the correct compilers are available the Dockerfile used with the Dev Container has all of the dependencies specified. It also uses Ubuntu 20.04 as the Raspberry Pi OS we are using is based off of Debian Buster. This ensures that we have a glibc version for our build machine that matches the target machine which is necessary to debug the application.<\/p>\n<h2>Using Visual Studio to target a Raspberry Pi<\/h2>\n<p>From Visual Studio\u00a0 \u00a02022 17.5 open the folder where you cloned the project locally. Visual Studio will prompt you to reopen in a Dev Container, do so unless you are configuring your WSL or Linux environment with the prerequisites found in the .devcontainer\\Dockerfile.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/devcontainergoldbar.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31507\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/devcontainergoldbar.png\" alt=\"Image devcontainergoldbar\" width=\"1560\" height=\"84\" \/><\/a><\/p>\n<p>Once the Dev Container is up select the Linux Debug preset configuration and the Debug target \u201cHello build machine\u201d in the toolbar. The debug configuration is provided by the .vs\/launch.vs.json that is part of the project.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/hellobuildmachine-vs.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31508\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/hellobuildmachine-vs.png\" alt=\"Image hellobuildmachine vs\" width=\"644\" height=\"50\" \/><\/a><\/p>\n<p>This will build the application to target the local build environment, then launch the application under debug. You can set a breakpoint on the sleep statement. The Linux Console will open for output, and for a Dev Container the output will be similar to the below.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/debugbuildmachine-vs.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31505\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/debugbuildmachine-vs.png\" alt=\"Image debugbuildmachine vs\" width=\"780\" height=\"284\" \/><\/a><\/p>\n<p>Now change your preset configuration to be either Linux Pi 3 Debug or Linux Pi 4 Debug depending on which device you have. Select the \u201cHello Pi\u201d debug configuration that is provided by the .vs\/launch.vs.json that is part of the project.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/hellopi-vs.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31509\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/hellopi-vs.png\" alt=\"Image hellopi vs\" width=\"671\" height=\"53\" \/><\/a><\/p>\n<p>Before debugging add your Raspberry Pi to the Connection Manager. From the toolbar select the Target System dropdown and select Manage Connections.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/targets-vs.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31510\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/targets-vs.png\" alt=\"Remote targets drop down in Visual Studio\" width=\"189\" height=\"215\" \/><\/a><\/p>\n<p>Here you can add your Raspberry Pi or remote Linux connection (note that IP address is more stable for the Raspberry Pi 3). Once this information is saved you need to set the remoteMachineName option to the connection you just added in the launch.vs.json. You can get to this file from Debug menu or right clicking the CMakeLists.txt in the Solution Explorer and selecting Debug and Launch Settings.<\/p>\n<p>Once your remote target is configured start the Hello Pi (Remote Debug) target. The build will run in the Dev Container, the output will be deployed to the target, and a gdb connection will be established. The Linux Console will open to display output and will appear similar to the below.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/debugpi-vs.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31506\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/debugpi-vs.png\" alt=\"Image debugpi vs\" width=\"780\" height=\"264\" \/><\/a><\/p>\n<h2>Using Visual Studio Code to target a Raspberry Pi<\/h2>\n<p>In VS Code you will want the CppTools and Remote Containers extensions installed, they will likely be suggested if not installed already. From open the folder where you cloned the project locally. VS Code will prompt you to reopen in a Dev Container, do so unless you are configuring your WSL or Linux environment with the prerequisites found in the .devcontainer\\Dockerfile.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/devcontainerpopup.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31523\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/devcontainerpopup.png\" alt=\"Image devcontainerpopup\" width=\"577\" height=\"175\" \/><\/a><\/p>\n<p>Once the Dev Container is up select the Linux Debug configuration, then you select the Debug target. You can do this from the status bar or the Debug pane.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/devcontainerstatusbar-vscode.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31521\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/devcontainerstatusbar-vscode.png\" alt=\"Image devcontainerstatusbar vscode\" width=\"779\" height=\"34\" \/><\/a><\/p>\n<p>Selecting debug will build the application to target the local build environment, then launch the application under debug. You can set a breakpoint on the sleep statement. Output from the application will be in the terminal. For a Dev Container the output will be similar to the below.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/debugincontainer-vscode.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31520\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/debugincontainer-vscode.png\" alt=\"Image debugincontainer vscode\" width=\"780\" height=\"208\" \/><\/a><\/p>\n<p>Now change your configuration to be either Linux Pi 3 Debug or Linux Pi 4 Debug depending on which device you have.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/presetconfigs-vscode.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31519\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/presetconfigs-vscode.png\" alt=\"Image presetconfigs vscode\" width=\"437\" height=\"163\" \/><\/a><\/p>\n<p>From the Debug Pane change the configuration from &#8220;Debug&#8221; to &#8220;Debug Pi&#8221;. These options are preconfigured in .vscode\/launch.json of the project.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/debugpi-vscode.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31518\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/debugpi-vscode.png\" alt=\"Image debugpi vscode\" width=\"448\" height=\"274\" \/><\/a><\/p>\n<p>When you start the debug session you will be prompted to select a SSH Target.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/addsshtarget-vscode.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31517\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/addsshtarget-vscode.png\" alt=\"Image addsshtarget vscode\" width=\"757\" height=\"119\" \/><\/a><\/p>\n<p>Since this is our first SSH target we need to select the option to add a new one. The first step is to give it a name.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/sshtargetname-vscode.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31516\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/sshtargetname-vscode.png\" alt=\"Image sshtargetname vscode\" width=\"755\" height=\"109\" \/><\/a><\/p>\n<p>Next provide the SSH command to connect to your Raspberry Pi, for example ssh user@host.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/sshcommand-vscode.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31515\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/sshcommand-vscode.png\" alt=\"Image sshcommand vscode\" width=\"744\" height=\"109\" \/><\/a><\/p>\n<p>You\u2019ll then be prompted for where to store the SSH connection, either in the user or a global location. In a Dev Container root is the user.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/sshconfig-vscode.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31514\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/sshconfig-vscode.png\" alt=\"Image sshconfig vscode\" width=\"751\" height=\"139\" \/><\/a><\/p>\n<p>The first time you connect to the device you will be prompted to accept the fingerprint.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/sshfingerprint-vscode.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31513\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/sshfingerprint-vscode.png\" alt=\"Image sshfingerprint vscode\" width=\"748\" height=\"139\" \/><\/a><\/p>\n<p>Finally, you will need to authenticate the user you selected for the connection.<\/p>\n<p>When the debug session starts the output for the remote SSH connection is in the output pane for Cpptools:SSH.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/sshoutput-vscode.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31512\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/sshoutput-vscode.png\" alt=\"Image sshoutput vscode\" width=\"780\" height=\"186\" \/><\/a><\/p>\n<p>The SSH connection can be found in the Debug panel CPPTOOLS: SSH TARGETS. If you have more than one they will be enumerated here and you can change which one is active. You can also start a terminal session to the SSH connection.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/sshtargets-vscode.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-31511\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/01\/sshtargets-vscode.png\" alt=\"Image sshtargets vscode\" width=\"424\" height=\"113\" \/><\/a><\/p>\n<h2>Send us your feedback<\/h2>\n<p>We hope that these new capabilities will enable you to choose Visual Studio and Visual Studio Code for your C++ development needs and make you more productive. We are very interested in your feedback to continue to improve this experience. The comments below are open, or you can find us on Twitter (<a href=\"https:\/\/twitter.com\/visualc\">@VisualC<\/a>), or via email at\u00a0<a href=\"mailto:visualcpp@microsoft.com\">visualcpp@microsoft.com<\/a>.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are a number of ways that Visual Studio and Visual Studio Code enable you to interact with remote machines. Both can enable you to connect to a remote machine and use it as a build machine and debug your applications there. Sometimes though your target is not the same as your build machine. For [&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":[1,292,3903],"tags":[],"class_list":["post-31506","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","category-containers","category-embedded"],"acf":[],"blog_post_summary":"<p>There are a number of ways that Visual Studio and Visual Studio Code enable you to interact with remote machines. Both can enable you to connect to a remote machine and use it as a build machine and debug your applications there. Sometimes though your target is not the same as your build machine. For [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/31506","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=31506"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/31506\/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=31506"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=31506"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=31506"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}