{"id":5773,"date":"2020-08-05T07:00:47","date_gmt":"2020-08-05T14:00:47","guid":{"rendered":"http:\/\/writeasync.net\/?p=5773"},"modified":"2020-08-01T15:59:22","modified_gmt":"2020-08-01T22:59:22","slug":"cross-platform-without-complexity-remote-linux","status":"publish","type":"post","link":"http:\/\/writeasync.net\/?p=5773","title":{"rendered":"Cross-platform without complexity: remote Linux"},"content":{"rendered":"<p>Previously, we showed <a href=\"http:\/\/writeasync.net\/?p=5765\">how to enable the Visual Studio IDE to work with an ostensibly cross-platform CMake project<\/a>. Today we will prove that the project indeed can work on a non-Windows platform &#8212; at least as much as is possible when using the <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/wsl\/about\">Windows Subsystem for Linux<\/a> (WSL).<\/p>\n<p>Let&#8217;s start by observing that <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/c-with-visual-studio-2019-and-windows-subsystem-for-linux-wsl\/\">Visual Studio has direct support for WSL<\/a>. While I do want to use WSL for this demo, I actually don&#8217;t want VS to <em>specifically<\/em> target WSL. Instead, let&#8217;s use the generic <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/linux\/connect-to-your-remote-linux-computer?view=vs-2019\">remote Linux<\/a> functionality instead. After appropriately configuring my WSL instance using simple password auth (<a href=\"https:\/\/linuxhandbook.com\/ssh-disable-password-authentication\/\">for use in <strong>local scenarios only<\/strong>, of course!<\/a>), we can add a remote connection for the WSL instance (e.g. using <code>::1<\/code> as the IPv6 localhost name and whichever port was chosen for SSH).<\/p>\n<p>Now we just need to instruct VS to <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/linux\/cmake-linux-project?view=vs-2019#configure_cmake_linux\">create CMake configurations<\/a> for <code>Linux-Clang-Debug<\/code> and <code>Linux-Clang-Release<\/code> (GCC is also supported, but <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/clang-support-msbuild?view=vs-2019\">Clang is somewhat better integrated with VS<\/a>). The <code>CMakeSettings.json<\/code> file now looks like this:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n{\r\n  &quot;configurations&quot;: &#x5B;\r\n    {\r\n      &quot;name&quot;: &quot;x64-Debug&quot;,\r\n      &quot;generator&quot;: &quot;Ninja&quot;,\r\n      &quot;configurationType&quot;: &quot;Debug&quot;,\r\n      &quot;inheritEnvironments&quot;: &#x5B; &quot;msvc_x64_x64&quot; ],\r\n      &quot;buildRoot&quot;: &quot;${projectDir}\\\\out\\\\build\\\\${name}&quot;,\r\n      &quot;installRoot&quot;: &quot;${projectDir}\\\\out\\\\install\\\\${name}&quot;,\r\n      &quot;cmakeCommandArgs&quot;: &quot;&quot;,\r\n      &quot;buildCommandArgs&quot;: &quot;&quot;,\r\n      &quot;ctestCommandArgs&quot;: &quot;&quot;,\r\n      &quot;variables&quot;: &#x5B;]\r\n    },\r\n    {\r\n      &quot;name&quot;: &quot;x64-Release&quot;,\r\n      &quot;generator&quot;: &quot;Ninja&quot;,\r\n      &quot;configurationType&quot;: &quot;RelWithDebInfo&quot;,\r\n      &quot;buildRoot&quot;: &quot;${projectDir}\\\\out\\\\build\\\\${name}&quot;,\r\n      &quot;installRoot&quot;: &quot;${projectDir}\\\\out\\\\install\\\\${name}&quot;,\r\n      &quot;cmakeCommandArgs&quot;: &quot;&quot;,\r\n      &quot;buildCommandArgs&quot;: &quot;&quot;,\r\n      &quot;ctestCommandArgs&quot;: &quot;&quot;,\r\n      &quot;inheritEnvironments&quot;: &#x5B; &quot;msvc_x64_x64&quot; ],\r\n      &quot;variables&quot;: &#x5B;]\r\n    },\r\n    {\r\n      &quot;name&quot;: &quot;Linux-Clang-Debug&quot;,\r\n      &quot;generator&quot;: &quot;Ninja&quot;,\r\n      &quot;configurationType&quot;: &quot;Debug&quot;,\r\n      &quot;cmakeExecutable&quot;: &quot;\/usr\/bin\/cmake&quot;,\r\n      &quot;remoteCopySourcesExclusionList&quot;: &#x5B; &quot;.vs&quot;, &quot;.git&quot;, &quot;out&quot; ],\r\n      &quot;cmakeCommandArgs&quot;: &quot;&quot;,\r\n      &quot;buildCommandArgs&quot;: &quot;&quot;,\r\n      &quot;ctestCommandArgs&quot;: &quot;&quot;,\r\n      &quot;inheritEnvironments&quot;: &#x5B; &quot;linux_clang_x64&quot; ],\r\n      &quot;remoteMachineName&quot;: &quot;${defaultRemoteMachineName}&quot;,\r\n      &quot;remoteCMakeListsRoot&quot;: &quot;$HOME\/.vs\/${projectDirName}\/${workspaceHash}\/src&quot;,\r\n      &quot;remoteBuildRoot&quot;: &quot;$HOME\/.vs\/${projectDirName}\/${workspaceHash}\/out\/build\/${name}&quot;,\r\n      &quot;remoteInstallRoot&quot;: &quot;$HOME\/.vs\/${projectDirName}\/${workspaceHash}\/out\/install\/${name}&quot;,\r\n      &quot;remoteCopySources&quot;: true,\r\n      &quot;rsyncCommandArgs&quot;: &quot;-t --delete --delete-excluded&quot;,\r\n      &quot;remoteCopyBuildOutput&quot;: false,\r\n      &quot;remoteCopySourcesMethod&quot;: &quot;rsync&quot;,\r\n      &quot;addressSanitizerRuntimeFlags&quot;: &quot;detect_leaks=0&quot;,\r\n      &quot;variables&quot;: &#x5B;]\r\n    },\r\n    {\r\n      &quot;name&quot;: &quot;Linux-Clang-Release&quot;,\r\n      &quot;generator&quot;: &quot;Ninja&quot;,\r\n      &quot;configurationType&quot;: &quot;RelWithDebInfo&quot;,\r\n      &quot;cmakeExecutable&quot;: &quot;\/usr\/bin\/cmake&quot;,\r\n      &quot;remoteCopySourcesExclusionList&quot;: &#x5B; &quot;.vs&quot;, &quot;.git&quot;, &quot;out&quot; ],\r\n      &quot;cmakeCommandArgs&quot;: &quot;&quot;,\r\n      &quot;buildCommandArgs&quot;: &quot;&quot;,\r\n      &quot;ctestCommandArgs&quot;: &quot;&quot;,\r\n      &quot;inheritEnvironments&quot;: &#x5B; &quot;linux_clang_x64&quot; ],\r\n      &quot;remoteMachineName&quot;: &quot;${defaultRemoteMachineName}&quot;,\r\n      &quot;remoteCMakeListsRoot&quot;: &quot;$HOME\/.vs\/${projectDirName}\/${workspaceHash}\/src&quot;,\r\n      &quot;remoteBuildRoot&quot;: &quot;$HOME\/.vs\/${projectDirName}\/${workspaceHash}\/out\/build\/${name}&quot;,\r\n      &quot;remoteInstallRoot&quot;: &quot;$HOME\/.vs\/${projectDirName}\/${workspaceHash}\/out\/install\/${name}&quot;,\r\n      &quot;remoteCopySources&quot;: true,\r\n      &quot;rsyncCommandArgs&quot;: &quot;-t --delete --delete-excluded&quot;,\r\n      &quot;remoteCopyBuildOutput&quot;: false,\r\n      &quot;remoteCopySourcesMethod&quot;: &quot;rsync&quot;,\r\n      &quot;addressSanitizerRuntimeFlags&quot;: &quot;detect_leaks=0&quot;,\r\n      &quot;variables&quot;: &#x5B;]\r\n    }\r\n  ]\r\n}\r\n<\/pre>\n<p>If your WSL instance has all the right packages installed (which could include <a href=\"https:\/\/packages.ubuntu.com\/bionic\/clang\">clang<\/a>, <a href=\"https:\/\/packages.ubuntu.com\/bionic\/gcc\">gcc<\/a>, <a href=\"https:\/\/packages.ubuntu.com\/bionic\/gdb\">gdb<\/a>, <a href=\"https:\/\/packages.ubuntu.com\/bionic\/libgtest-dev\">libgtest-dev<\/a>, <a href=\"https:\/\/packages.ubuntu.com\/bionic\/make\">make<\/a>, <a href=\"https:\/\/packages.ubuntu.com\/bionic\/ninja-build\">ninja-build<\/a>, <a href=\"https:\/\/packages.ubuntu.com\/bionic\/rsync\">rsync<\/a>, and <a href=\"https:\/\/packages.ubuntu.com\/bionic\/zip\">zip<\/a>), the remote build target should properly produce a debug or release build with <a href=\"https:\/\/en.wikipedia.org\/wiki\/Executable_and_Linkable_Format\">ELF binaries<\/a>.<\/p>\n<p>To verify this, we can login to the WSL instance and locate the temporary output path that VS used to produce the build:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nuser@MACHINE:~\/.vs\/CMakeSampleVS\/7f954387-c6bd-4590-b386-6f2e8cdbc5b2\/out\/build\/Linux-Clang-Debug$ .\/sample-app Linux\r\nHello, Linux!\r\nuser@MACHINE:~\/.vs\/CMakeSampleVS\/7f954387-c6bd-4590-b386-6f2e8cdbc5b2\/out\/build\/Linux-Clang-Debug$ .\/sample-test\r\nRunning main() from gtest_main.cc\r\n&#x5B;==========] Running 1 test from 1 test case.\r\n&#x5B;----------] Global test environment set-up.\r\n&#x5B;----------] 1 test from SampleTest\r\n&#x5B; RUN      ] SampleTest.GetName\r\n&#x5B;       OK ] SampleTest.GetName (0 ms)\r\n&#x5B;----------] 1 test from SampleTest (1 ms total)\r\n\r\n&#x5B;----------] Global test environment tear-down\r\n&#x5B;==========] 1 test from 1 test case ran. (4 ms total)\r\n&#x5B;  PASSED  ] 1 test.\r\n<\/pre>\n<p>Success!<\/p>\n<p>Here is the GitHub repo with the changes up to this point: <a href=\"https:\/\/github.com\/bobbymcr\/CMakeSampleVS\/tree\/7eb3be828b59cea5d8b9cb024245e321473a5ade\">CMakeSampleVS<\/a><\/p>\n<p>It appears that everything works on Linux. The final frontier is the command line &#8212; how can we replicate the above build and test steps from the comfort of the console? We&#8217;ll see next time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Previously, we showed how to enable the Visual Studio IDE to work with an ostensibly cross-platform CMake project. Today we will prove that the project indeed can work on a non-Windows platform &#8212; at least as much as is possible&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[107,101],"tags":[],"class_list":["post-5773","post","type-post","status-publish","format-standard","hentry","category-cross-platform","category-native"],"_links":{"self":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/5773","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5773"}],"version-history":[{"count":5,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/5773\/revisions"}],"predecessor-version":[{"id":5780,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/5773\/revisions\/5780"}],"wp:attachment":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5773"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5773"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5773"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}