antek's tech blog - visualstudioZola2018-11-22T00:00:00+00:00https://anadoxin.org/blog/tags/visualstudio/atom.xmlBringing Visual Studio compiler into MSYS2 environment2018-11-22T00:00:00+00:002018-11-22T00:00:00+00:00Unknownhttps://anadoxin.org/blog/bringing-visual-studio-compiler-into-msys2-environment.html/<p>Using Windows is a painful experience for a command-line oriented person like me. Unfortunately, Windows doesn't offer any decent command-line oriented environment, because well, it has different goals, and that's understandable. The problem is when one is forced to use Windows when it's clear that those goals are incompatible with the person's goals.</p>
<p>One solution is to use <a href="https://www.msys2.org">MSYS2</a> environment. It's a msys/cygwin-like shell that effectively provides you with a bash shell, and this runs on Windows. Of course it's not as fast as a native Linux shell, but still it's better than nothing. And it uses <code>pacman</code> from ArchLinux!</p>
<p>(one trick: MSYS2 also allows you to run <code>sshd</code>, and you'll be able to <code>ssh</code> into your Windows boxes the same way you can ssh on your Linux machines)</p>
<p>Another solution would probably be WSL (Windows Subsystem for Linux), but honestly last time I've checked the state of this, a simple <code>ls -la</code> took 2 seconds everytime it was run, and <code>apt-get update</code> took probably half of an hour of constant disk swapping. I've lost patience, aborted WSL session and promised myself to look into this after a year. This year has not passed yet.</p>
<p>So, after installing MSYS2 you're going to need a development environment. It's easy to install MinGW's <code>gcc</code> with <code>pacman</code>, as well as <code>clang</code> so you can proof-test your C++ code with different compilers. But since we're on Windows, we can do better, and we can actually hack our way into integrating Visual Studio with MSYS2 shell, so we'll be able to use Visual Studio's development tools directly from MSYS2.</p>
<p>This has several advantages, but mostly it's convinient if you're forced to either:</p>
<ul>
<li>
<p>Make the project compilable on different compilers, like GCC, Clang and Visual Studio,</p>
</li>
<li>
<p>You're interested in how different compilers generate assembly from your C++ source,</p>
</li>
<li>
<p>You have to work using Visual Studio, but you're not a Windows person,</p>
</li>
<li>
<p>I'm sure you can find more arguments for it ;).</p>
</li>
</ul>
<p>The approach taken in this note is to install Visual Studio, open its command-line tools window that allow you to use command-line Visual Studio tools, snapshot its environment, and re-create this environment in your <code>~/.bashrc</code> from MSYS2.</p>
<h3 id="install-visual-studio">Install Visual Studio</h3>
<p>So the first step is to install Visual Studio Community edition, because it's free. And it contains all the tools we need, skipping all the tools we don't need. I won't provide you with a direct link to Microsoft's site, because any link pointing to them dies faster than a hope for humanity after watching YouTube, that's why I'll just simply link to a DuckDuckGo <a href="https://duckduckgo.com/?q=microsoft+visual+studio+community&t=ffsb&ia=web">search query</a>, and you should be able to find the proper link on the first page (hopefully it will be the first link, but with DuckDuckGo you'll never know).</p>
<p>One fun fact during installation of Visual Studio is that you better install it on your C drive, because if you'll select some other drive, it will still mostly install itself on C drive. So I'm not sure it's worth splitting the installation to two drives. I'm always installing it to C.</p>
<p>After installing, Visual Studio will provide some convinient shortcuts in the glorious Start menu (which is apparently more important than the kernel itself). One of those shortcuts is called:</p>
<pre><code>Visual Studio 2017/Command line for x64 Native Tools for Visual Studio 2017
</code></pre>
<p>Or something like this, as it also depends on the language version of your system.</p>
<p>Just run this shortcut, and you'll be greeted with a black console window that contains all the necessary setup in order to run command-line Visual Studio tools. Don't close this window yet; we'll need it later.</p>
<h3 id="install-envdiff">Install envdiff</h3>
<p>I've prepared a <a href="https://gitlab.com/antekone/envdiff">small tool</a>, <code>envdiff</code>, that will dump the environment variables of the current shell. It's very small and primitive, but this only means that there are not many things than can break (then again, it's Windows we're talking about).</p>
<p>You'll need <code>Rust</code> compiler in order to compile <code>envdiff</code>, but don't worry, <a href="https://www.rust-lang.org/en-US/install.html">installing Rust</a> is really fast, it's nowhere near the bloated Visual Studio installer.</p>
<p>You can compile <code>envdiff</code> like this (you can do it under MSYS2 shell):</p>
<pre data-lang="nothing" class="language-nothing "><code class="language-nothing" data-lang="nothing">$ cd ~/dev
$ mkdir envdiff && cd envdiff
$ git clone https://gitlab.com/antekone/envdiff.git .
$ cargo build --release
Downloading ...
Downloading ...
Compiling ...
Compiling ...
...
$ ls -la target/release/envdiff.exe
</code></pre>
<p>First compilation will take a while, because it will need to download and compile all dependencies for JSON serialization, which the tool uses. The resulting binary file will be placed in the <code>target/release/envdiff.exe</code> file.</p>
<h3 id="snapshot-the-environment-of-a-clean-shell">Snapshot the environment of a clean shell</h3>
<p>Next step is to open a normal <code>cmd.exe</code> shell to open a black terminal with a clean shell. Then you can run <code>envdiff.exe</code> you've build in your previous step.</p>
<pre data-lang="nothing" class="language-nothing "><code class="language-nothing" data-lang="nothing">C:\> cd c:\msys64\home\antek\dev\envdiff
C:\msys64\home\antek\dev\envdiff> target\release\envdiff.exe
Stored snapshot.env
</code></pre>
<p>This output means that your current environment has been stored inside the <code>snapshot.env</code> file.</p>
<h3 id="diff-clean-environment-with-visual-studio-environment">Diff clean environment with Visual Studio environment</h3>
<p>Remember the Visual Studio command-line tools console box I've told you to not close earlier? You can bring it back now. Enter the same directory that you've used previously, the one with the <code>snapshot.env</code> file, and run <code>envdiff.exe</code> again, but remember to use the Visual Studio command-line tools console box this time.</p>
<pre data-lang="nothing" class="language-nothing "><code class="language-nothing" data-lang="nothing">**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.8.7
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community> cd c:\msys64\home\antek\dev\envdiff
C:\msys64\home\antek\dev\envdiff> target\release\envdiff.exe
...
</code></pre>
<p>This time it will display the environment in the <code>bash</code> syntax that you need to append to your <code>~/.bashrc</code> file. You can do a helper bash script like this:</p>
<pre data-lang="nothing" class="language-nothing "><code class="language-nothing" data-lang="nothing">C:\msys64\home\antek\dev\envdiff> target\release\envdiff.exe > c:\msys64\home\antek\.visualstudio.sh
</code></pre>
<p>Then, under MSYS2, just edit your <code>~/.bashrc</code> and put this line at the end of this file:</p>
<pre data-lang="sh" class="language-sh "><code class="language-sh" data-lang="sh">source ~/.visualstudio.sh
</code></pre>
<h3 id="relogin-check-if-it-works">Relogin, check if it works</h3>
<p>Run a new MSYS2 terminal and check if it works:</p>
<pre data-lang="nothing" class="language-nothing "><code class="language-nothing" data-lang="nothing">antek@MORDOR MSYS ~
$ cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.15.26730 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
usage: cl [ option... ] filename... [ /link linkoption... ]
antek@MORDOR MSYS ~
$ msbuild.exe
Microsoft (R) Build Engine version 15.8.169+g1ccb72aefa for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.
</code></pre>
<p>It should work and you should be able to produce Visual Studio-generated executables directly from your MSYS2 shell.</p>
<h3 id="gotchas">Gotchas</h3>
<p>There's one name collision. MSYS2 already has an executable <code>/bin/link.exe</code> in current PATH variable, and Visual Studio uses its own <code>link.exe</code> to link object files to executable files. The <code>/bin/link.exe</code> file will have to be renamed to i.e. <code>/bin/link2.exe</code> to get Visual Studio tools to work properly. I'm not sure if anything uses <code>/bin/link.exe</code> though, after renaming it I haven't noticed any breakages.</p>
<p>Another issue is that CMake's Visual Studio 2017 (or 2019) generator won't work when you try to do it from <code>ssh</code> shell. Solution for this is to install <code>sshd</code> as a system service running in the context of <code>SYSTEM</code> user (so, with admin rights). Then finding VS installation will work, thus CMake will work without problems. Setting up <code>sshd</code> as a system service is unfortunately out of scope of this blog post, so I'll maybe create a new one instead in the future. In the meantime, you can check <a href="https://gist.github.com/samhocevar/00eec26d9e9988d080ac">this</a> script, it worked for me (with some modifications).</p>
<p>Hope this works for you!</p>