Skip to main content

Get Away MSVC, Hello MSYS2

!!! For Windows, I am a noob !!!

Why not MSVC?

For C++ developer, there is no so many useable IDE on Windows, most of us are using Visual Studio.

For C++ project, I am not familiar with VS’s sln, I prefer to use CMake. CMake is a cross platform tool and could be read easier.

For projects using CMake, VS is the worst choice. VS’s CMake support is not completely.

Use or compie C++ libraries on windows is a nightmare.

For example, a project which depends on boost, how to compile this project on linux?

Just install boost-libs by linux distro’s package manager.

When we using linux-amd64, it will only install the depends which the platform is amd64, we will not worry about the platform.

But MSVC is different.

For example, on github actions’ Windows Server2019, the buildin boost 1.72.0 is msvc win32 prebuild, we need specify platform when generate makefiles. It will find 64-bit libraries if platform is not specify.

cmake -G "Visual Studio 16 2019" -A Win32 -B build
cmake --build build

Although the platform is correct, the corresponding makefiles are generated, we will still get some unreasonable error because of the msvc when we compile. 4_build.txt

I think mingw is a better choice.

Why MSYS2?

I tried chocolatey and vcpkg, they don’t have prebuild binaries and they are more focus on MSVC.

Is there any better toolchains? Welcome MSYS2!

MSYS2 is a software distro based on mingw64. MSYS2 use pacman as package manager, just like my favorite distro: ArchLinux.

MSYS2 have two buildin repos, mingw64 and msys.

mingw64 offers tools work for Windows. Such as python, its package name is mingw-w64-x86_64-python.

msys offers tools work for MSYS2 shell, such as wget.

An Example

Let’s use my project supersm as compile example to see if it works.

This project is using boost, C++11 is specified in CMakeLists.txt.

Compile is easy, just two steps: generate and build

We are using mingw64, cmake needed to specify Generators as “MinGW Makefiles”

cmake -G "MinGW Makefiles" -B build
cmake --build build

Build the develop environments is also very simple, which tools should be installed by MSYS2?

cmake is neccessary, aka. mingw64/mingw-w64-x86_64-cmake

We need gcc libs and boost libs: mingw64/mingw-w64-x86_64-gcc mingw64/mingw-w64-x86_64-boost

Why we use gcc not clang? I will write below.

Install them is as simple as using Linux.

pacman -S mingw64/mingw-w64-x86_64-cmake mingw64/mingw-w64-x86_64-gcc mingw64/mingw-w64-x86_64-boost

Then we add the msys64\mingw64\bin and msys64\mingw64\include (absolute path) to PATH, they would be found automatically.

Setup Editor

Which IDE we should use without Visual Studio?

My choice is not IDE, I prefer to use neovim recently, simple listing of C++ related plugins

Install vim-plug

First of all, we need a plugin manager to install plugins, I choose vim-plug.

md ~\AppData\Local\nvim\autoload
$uri = 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
(New-Object Net.WebClient).DownloadFile(
  $uri,
  $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(
    "~\AppData\Local\nvim\autoload\plug.vim"
  )
)

Install coc

I am using coc.nvim for code compiling, coc required nodejs, use node -v or npm -v to test whether it detected.

Writing to ~\AppData\Local\nvim\init.vim

call plug#begin('~/.vim/plugged')
Plug 'neoclide/coc.nvim', {'branch': 'release'}
call plug#end()

:source ~\AppData\Local\nvim\init.vim to reload vimrc. (I created a symlink to ~\_vimrc)

Run :PlugInstall to install coc.

And reload again, coc will be able to used.

Install and setup lsp

Code completion is provided by lsp(Language Server).

For C++ lsp, we can choose ccls, cquery, clangd.

ccls is forked from cquery, clangd is a part of clang (LLVM).

I choose clangd, it is faster.

Install clang by MSYS2:

pacman -S mingw64/mingw-w64-x86_64-clang

We need enable clangd in coc’s setting. :CocConfig to open coc-setting.json.

{
  "languageserver": {
    "clangd": {
      "command": "clangd",
      "rootPatterns": ["compile_flags.txt", "compile_commands.json"],
      "filetypes": ["c", "cpp", "objc", "objcpp"]
    }
  }
}

clangd uses compile_commands.json to detect the project, cmake can generate this file

cmake -G "MinGW Makefiles" -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -B build
copy .\build\compile_commands.json .\