Help us understand the problem. What is going on with this article?

【VScode+WSLで始める】競プロ用C++デバッグ環境構築

はじめに

VScodeWSLでのC++のデバッグ環境を整えます.
何番煎じかわかりませんが自分で,これだ.というものに巡り会えていないため備忘録も兼ねてこの記事を書いています.
これからC++で競プロを始める人の参考になれば幸いです.
デバッグは環境構築と簡単な使い方について説明します.

目標

AtCoderでC++を使って競技プログラミングを行うことを想定しています.

基本動作は,
1. Ctrl+Shift+Bで自動コンパイル.
2. 統合ターミナルより手動で実行.入力を与え,出力結果を確認.
3. 必要になったらVScodeのデバッグ機能(F5)を使用してデバッグ.

最終的にフォルダの構成は以下のようになります.
2019-07-03_04h23_10.png

  • 各コンテスト毎にフォルダを作成し,その中にA問題だったらa.cppのようなファイル名でどんどん作成していきます.
  • プログラムの実行ファイルはディレクトリ直下に生成されるようにします.
  • Vscodeのデバッグ機能を使用してデバッグを行う際,統合ターミナルからの入力を受け付けて貰えないため,リダイレクトで標準入力として与えます.そのためproblem.inというファイルを用意し,そこに問題の入力を入れておきます.

前提

VScodeWSLに関してはインストール済みであるとします.
以下は自分の環境です.

Version
Windows Windows 10 Home(1903)
VScode 1.36.1
WSL Ubuntu 16.04.6 LTS

WSLでは現在多くのLinuxディストリビューションに対応しています.
C++のコンパイル・デバッグに関して言えばほとんどのディストリビューションで可能なので自由に好きなものを選んで頂いて構いません.

C++実行環境構築

初めにVScode上でC++ファイルのコンパイルと実行を行えるようにしていきます.

WSL環境

WSL端末を開き,以下のコマンドでg++gdbをインストールします.

WSL
sudo apt install build-essential
sudo apt install gdb

VScode環境

拡張機能のインストール

C/C++用の拡張機能をインストールします.
赤枠で囲った拡張機能のところで検索欄に「C++」と検索して出てくる次の2つをインストールしてください.
以下のURLからでもインストールすることができます.

C/C++
2019-07-02_16h51_09.png

C++ Intellisense
2019-07-02_16h51_17.png

統合ターミナルの設定

標準で使うターミナルをWSLに設定します.
Ctrl+Shift+Pを押してコマンドパレットを表示させ,「shell」と入力し,Select Default Shellを選択します.
2019-07-02_16h56_50.png

すると何種類からかシェルを選ぶことができるのでそこからWSL Bashを選択します.

2019-07-02_16h57_02.png

ツールバーのTerminal -> New Terminalを選択するか,Ctrl+Shift+@を押すことによってターミナルを開きます.
次の矢印のようにWSLターミナルが開かれていることを確認してください.

2019-07-02_17h05_16.png

tasks.jsonの設定

Ctrl+Shift+Bで現在開いているファイルをビルドする設定を行います.
なにも設定を行っていない状態でCtrl+Shift+Bを押すと次のような表示が出てくると思うのでとりあえず指示にしたがってクリックしていきます.
2019-07-02_17h18_00.png

2019-07-02_17h18_07.png

ここで選択肢が4つ出てくるのでOthersを選択します.
2019-07-02_17h18_20.png

.vscode内に次のようなtasks.jsonが生成されればOKです.
2019-07-02_17h18_40.png

そして生成されたtasks.jsonを次のように書き換えます.

tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "options": {
                "shell": {
                    "executable": "C:\\Windows\\System32\\wsl.exe",
                }
            },
            "command": "g++",
            "args": [
                "-std=gnu++1y",
                "-g",
                "-O0",
                "-I/opt/boost/gcc/include",
                "-L/opt/boost/gcc/lib",
                "-o",
                "`wslpath",
                "'${workspaceFolder}\\problem.exe'`",
                "`wslpath",
                "'${file}'`",
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

ここで簡単にコンパイルオプションについて解説します.
AtCoder側でのコンパイルオプションはこのサイトで確認することができます.

今回はC++14 (GCC 5.4.1)を選択するので,それためのコンパイルオプションをそのまま使用したいのですが,デバッグの関係上少しいじります.サイトのオプションと比較するとわかると思いますが,-O2ところを-O0としています.これは最適化オプションといって最適化の具合を指定することができ,-O0とすることによって最適化を無効とします.
最適化を行うことによって処理の順番が変わったり,コンテナの中身が見れなくなったりするのでデバッグを使用する際は最適化を無効にしましょう.

また,ファイルパスの前についているwslpathというのはWindows環境のパスをWSL環境のパスに変換するコマンドです.

IntelliSenseの設定

次にIntelliSenseの設定を行います.
先ほどと同じようにCtrl+Shift+Pをタイプしてコマンドパレットを出します.
C/C++:Edit Configurations(JSON)を探して選択してください.
2019-07-02_17h38_19.png
すると次のようにc_cpp_properties.jsonが生成されます.
2019-07-02_17h38_46.png
c_cpp_properties.jsonの中身を次のように書き換えてください.

c_cpp_properties.json
{
    "configurations": [
      {
        "name": "WSL",
        "intelliSenseMode": "gcc-x64",
        "compilerPath": "/usr/bin/gcc",
        "includePath": ["${workspaceFolder}/**"],
        "defines": [],
        "cStandard": "c11",
        "cppStandard": "c++17"
      }
    ],
    "version": 4
}

C++実行環境の確認

ここまででコンパイルから実行までできる環境が整いました.
それの確認を実際のAtCoderの問題を使用して行いたいと思います.
問題は初心者向けということでABC 086 A - Product(奇数偶数判定)をやっていきます.

初めに次のような階層にファイルを作成し,実装を行います.
2019-07-02_18h19_05.png

a.cpp
#include <bits/stdc++.h>
using namespace std;

int main(void)
{
    int a, b;
    cin >> a >> b;
    if ((a * b) % 2 == 0) cout << "Even" << endl;
    else cout << "Odd" << endl;    
}

ソースが完成したらCtrl+Shift+Bでコンパイルを行います.
コンパイルしてできた実行ファイルはディレクトリ直下にproblem.exeで生成されます.
2019-07-02_18h22_06.png

ターミナルに戻ったら,./problem.exeを実行して下さい.
入力を与えて所望の出力を得ることができたらC++実行環境の構築は成功です.
2019-07-02_18h36_46.png

デバッグ環境構築

次にデバッグをするための設定を行っていきます.

launch.jsonの設定

tasks.jsonと同じように何も設定していない状態でF5を押すと,上から選択画面が出てくるのでC++(GDB/LLDB)を選択してください.
2019-07-03_04h49_57.png
すると次のようなlaunch.jsonというファイルが.vscode内に生成されます.
2019-07-03_04h50_30.png

先ほどと同じようにこちらも書き換えてください.

launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Bash on Windows Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${command:extension.vscode-wsl-workspaceFolder}/problem.exe",
            "args": ["<", "${command:extension.vscode-wsl-workspaceFolder}/problem.in"],
            "stopAtEntry": false,
            "cwd": "${command:extension.vscode-wsl-workspaceFolder}",
            "environment": [],
            "externalConsole": true,
            "pipeTransport": {
                "debuggerPath": "/usr/bin/gdb",
                "pipeProgram": "${env:windir}\\system32\\bash.exe",
                "pipeArgs": ["-c"],
                "pipeCwd": "/"
            },
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "sourceFileMap": {
                "${command:extension.vscode-wsl-workspaceFolder}": "${workspaceFolder}"
            },

        }
    ]
}

${command:extension.vscode-wsl-workspaceFolder}部分でエラーが発生すると思うので,次のVScode拡張をインストールしてください.

WSL workspaceFolder
2019-07-03_05h01_49.png

この拡張ではワークスペースフォルダのパスをWSL環境のパスに変換します.
これがなくてもできないことはないですが,汎用性を上げるために使用しています.

デバッグ環境の確認

ここまでくれば(おそらく)デバッグ環境の構築はできていると思います.
先ほどと同じように確認していきましょう.

この環境でデバッグを行う際には,まずソースファイルの任意の行にブレークポイントを設定します.
ブレークポイントとは処理を一旦そこで止めるポイントです.
下の図のようにソースファイルの左側をクリックすることで赤い丸をつけることが出来ます.これがブレークポイントです.

次に入力する値を入れます.AtCoderのコンテストサイトからテストケースなどをコピーして,problem.inに貼り付けます.
2019-07-03_12h10_30.png
F5を押すと左側の画面が遷移し,デバッグの結果を見ることが出来ます.
デバッグ中だと下のバーがオレンジ色になり,上にツールバーが表示されます.
VARIABLESの欄に変数一覧とその値が表示されたら成功です.
2019-07-03_12h20_16.png

VScodeのデバッグ機能の使い方

VScodeのデバッグ機能の使い方について簡単に説明します.

ツールバー

上に表示されるツールバーでプログラムの流れを制御することが出来ます.
(iの値に注目)
2019-07-03_16h25_19.gif

ツールバーの各ボタンについて見ていきます.
2019-07-03_12h45_09.png

要素 ショートカット 機能
Continue/Pause F5 次のブレークポイントまで進める/プログラムを止める
Step Over F10 現在行を実行する.その行に関数呼び出しが含まれる場合は,その関数を呼び出して実行した後,次の行へ移動する.
Step Into F11 現在行を実行する.その行に関数呼び出しが含まれる場合は,その関数の先頭行へ移動する.std::sort()など組み込み関数を呼び出すとエラーになる.
Step Out Shift+F11 現在実行中の関数を抜けるまで処理を進める.
Restart Ctrl+Shift+F5 プログラムを最初からやり直す.
Stop Shift+F5 デバッグを終了する.

VARIABLES

ここでは変数の現在の値を確認することが出来ます.
配列はもちろん,コンテナクラスやpairの値も覗くことができます.
下のGIFではvectorの中身をソートして,その変化をデバッグ画面から確認する例です.
2019-07-03_16h09_39.gif

WATCH

WATCH欄では変数以外にもa+ba[i]などの式の値も見ることが出来ます.
下のGIFではちょっと分かりづらいですが,vectorのi番目の要素とその和と積をリアルタイムで確認しています.
2019-07-03_16h25_19.gif

CALL STACK

呼び出し中の関数を確認することが出来ます.
フィボナッチ数列などの再帰関数を定義している場合はこんな感じで表示されます.
2019-07-03_16h34_28.png

他にも便利な機能があるようなので調べて見ると面白いかもです.

最後に

VScodeとWSLを用いたC++のデバッグ環境構築を行ってきました.
環境構築って大変ですがその後のモチベーションにも関わってくる部分なので案外大切です.
この記事以外にもVScodeを用いた競プロ環境構築関連の記事は多くあるので,その中から「これはいい!使える!」といった部分を見つけて,自分自身のプログラミング環境を整えていくといいと思います(自分でいろいろ試す,というのが一番成長につながります!).
最初の頃はprintfでデバッグをしていましたが,デバッガが使えると競プロ以外でもかなり捗ります.おすすめです.

[2019/12/15追記]
コンパイル対象ファイルと同ディレクトリに実行ファイルを作成したい場合,コメント欄を参考にtasks.jsonlaunch.jsonの記述を書き換えてください.

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした