CountZero's blog

By CountZero, 3 years ago, In English

Hello. This is kind of continuation of this post https://codeforces.me/blog/entry/102287. In this tutorial I'll try to explain how to write and compile C++ code on Windows, using tools provided by (mostly) Microsoft. I'm going to use latest versions.

Terminal

First of all, let's install Windows Terminal and MS PowerShell. Standart windows command line is just not usable. Let's also install winget — this is a package manager similar to, for example, homebrew. Maybe chocolatey is better but, again, this one is developed by Microsoft.

Of course Microsoft Store isn't mandatory, you can use any other source for these packages.

I'd also suggest to try starship command prompt — very useful tool, supports powershell as well.

Compilers and tools

Open powershell and install Visual Studio 2022 Build Tools:

winget install Microsoft.VisualStudio.2022.BuildTools

This package actually installs the installer without any components. Now run this installer: type appwiz in powershell, find "Visual Studio Build Tools 2022" in the list, right click, "change". Open "Individual components" tab and look for the following:

  • MSVC ver. 143 (or later) for your platform
  • C++ clang for Windows
  • cmake
  • Windows SDK (latest version for your platform; I'm using Windows 11 SDK version 10.0.22000.0)

Run this installer from time to time to check for updates

Developer command prompt

In order to properly use all these compilers, you need to set up PATH and other environment variables. Microsoft provides special scripts for that. The usual suggestion is to just open "Visual Studio Developer Command Prompt" from your start menu, but we can actually do it much better. Let's use vssetup powershell module:

Install-Module vssetup -Scope CurrentUser
$i = (Get-VSSetupInstance)
Import-Module "$($i.InstallationPath)/Common7/Tools/Microsoft.VisualStudio.DevShell.dll"
Enter-VsDevShell $i.Instanceid -DevCmdArguments '-arch=amd64 -host_arch=amd64'

Replace amd64 with your desired architecture and save this script to file, say devshell.ps1. Now run this script in powershell and you'll get a proper development environment (devshell, as I call it). You can try compiling your code at this point: write something and type clang -std=c++20 program.cpp.

Editor

Yeah, I know that Microsoft provides its Visual Studio Code but I personally don't like this editor (it was too slow on my old laptop when I was a poor student. I'm not poor anymore, but still!). So let's install Sublime Text:

winget install SublimeHQ.SublimeText.4

Add sublime text installation folder to your PATH so you'll be able to launch it from console by typing subl. Run

rundll32 sysdm.cpl,EditEnvironmentVariables

Run freshly installed sublime text, open menu by hitting Ctrl+Shift+P, and select "Install package control". Open this menu again and select "Install Package — LSP".

LSP provides code diagnostics, navigation ("go to definition"), autocompletion and code formatting capabilities, We got clangd for C++, let's set it up. Open "Preferences — Package Settings — LSP — Settings" and look for "clangd" on the left pane. Copy it to the right pane, so your "LSP.sublime-settings" file should look something like

{
  "clients": {
     "clangd": {
       "enabled": true,
       "command": [
         "clangd",
         "--compile-commands-dir=build"
       ],
       "selector": "source.c | source.c++ | source.objc | source.objc++",
       "auto_complete_selector": "punctuation.accessor | (meta.preprocessor.include string - punctuation.definition.string.end)",
    },
  }
}

Clangd requires JSON compilation database (file compile_commands.json) to work properly. --compile-commands-dir=build tells it that this file is located in build subdirectory.

Keep in mind that sublime text should be launched from devshell, otherwise it won't be able to find clangd and everything else.

C++ project

I'm going to use cmake here. Cmake is a tool which generates build files for various build systems. Sublime text build system is supported as well, so let's use it! Create file CMakeLists.txt with the following content:

cmake_minimum_required(VERSION 3.21)

set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang)
set(CMAKE_EXPORT_COMPILE_COMMANDS on)

project(contest)

foreach(problem A B C)
        add_executable($$${problem} $$${problem}.cpp)
        target_compile_features(${problem} PRIVATE cxx_std_20)
endforeach()

(I have no idea why it keeps replacing 1 dollar sign with 3. Anyway, it should be 1). It assumes that you have a contest with 3 problems named A, B, C; you use clang and C++20. Now

mkdir build
cd build
cmake -G"Sublime Text 2 - Ninja" ..

you'll notice the file contest.sublime-project in your build folder. Open it in sublime text:

subl .\build\contest.sublime-project

Write something useful in A,cpp, select the appropriate build system (Tools — Build system — "contest — A") and hit Ctrl+B. Your file will be compiled. If you want to compile from console, type ninja A (or ninja -C build A depending of directory).

That's it I guess? My initial idea was to also write about visual debugger (https://github.com/daveleroy/sublime_debugger) but I actually almost don't use it

  • Vote: I like it
  • +19
  • Vote: I do not like it

»
3 years ago, # |
  Vote: I like it +14 Vote: I do not like it

I don't use Windows, but I think most people on CF use g++ as their compiler while submitting (it's useful for stuff like __builtin_* some of which have different names on clang-provided builtins), so it would be better to add that to the blog for the sake of completeness.

  • »
    »
    3 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    if you mean clz/ctz/popcount then there are standart headers https://en.cppreference.com/w/cpp/header/bit

    also, it's bad idea to use __builtin functions anyway

    • »
      »
      »
      3 years ago, # ^ |
        Vote: I like it +3 Vote: I do not like it

      I know about the bit header. However, I am talking about stuff like __builtin_mul_overflow and stuff, which I tend to use from time to time. AFAIK, some SIMD builtins don't work the same way with clang either, and I haven't been able to find an analogue for GCC optimization pragmas for clang (that work by adding a few lines in the source code), probably because it's considered bad practice in real-life code. It's not just builtins, but GCC extensions that make stuff easier (though I still compile with -pedantic most of the times lol).