73
109

More than 3 years have passed since last update.

WSL2 + Docker + VSCode で C++ と Python の実行環境を作る

Last updated at Posted at 2021-01-03

競プロで C++ と Python を使っていて,Windows での実行環境が欲しかったので作ってみました.
開発用ではないので必要最低限の設定になっています.

2020/1/11: VSCode 上で C++ 17 の文法を使えるようにする「C++ Standard の設定」を追加しました

対象

  • C++ や Python の簡単な実行環境を作りたい方
  • Windows ユーザ
    • Docker 導入済み
  • VSCode を使っている方

使用環境 / ツール

  • GitHub
  • Windows 10 + WSL2
  • Docker Desktop for Windows (v3.0.0)
  • VSCode (v1.52.1)

この記事で作れる実行環境のサンプルリポジトリ : https://github.com/e5pe0n/algo-training-sample

GitHub にリポジトリを作る

コードを管理しやすいように GitHub にリポジトリを作ります.
適当な Repository Name を入力し,Add a README file にチェックを入れて Create Repository をクリックします.
.gitignore はあとから作るのでここではチェックしません.

Create a New Repository - Google Chrome 1_3_2021 11_50_21 AM (2)_LI.jpg

Dev Container の作成

いま作ったリポジトリを,実行環境となる Docker コンテナにクローンします.

VSCode に Remote Development を入れる

まずは VSCode からコンテナに接続できるように, VSCode を開いて拡張機能 Remote Development (ms-vscode-remote.vscode-remote-extensionpack) をインストールします.

Extension_ Remote Development - Visual Studio Code 1_3_2021 12_01_58 PM.png

VSCode と GitHub を紐づける

インストールが完了すると,エディタの一番左下に Remote Development の機能が使える緑色のボタンが表示されるので,それをクリックします.
出てきたメニューの中から Remote-Containers: Clone Repository in Container Volume をクリックします.

Extension_ Remote Development - Visual Studio Code 1_3_2021 12_03_34 PM_LI.jpg

リポジトリの URL を入力してエンターを押します.

Extension_ Remote Development - Visual Studio Code 1_3_2021 12_03_57 PM (2).png

初回では,VSCode で GitHub アカウントにサインインするかのダイアログが表示されたり,ブラウザに飛んで VSCode が GitHub にアクセスすることを許可するか聞かれたりするので,それぞれ Yes や Continue をクリックします.

Extension_ Remote Development - Visual Studio Code 1_3_2021 12_04_05 PM.png
GitHub for VS Code - Google Chrome 1_3_2021 12_04_28 PM (3).png
Visual Studio Code 1_3_2021 12_05_25 PM.png

クローンするブランチ

VSCode と GitHub が紐づけられると,クローンするブランチを聞かれるので main を選択します.
Visual Studio Code 1_3_2021 12_06_16 PM (2).png

ボリュームの種類

ほかのリポジトリと併用しないので今回は Create a unique volume を選択します.
Welcome - Visual Studio Code 1_3_2021 12_07_36 PM (2).png

コンテナの種類

コンテナの種類は Ubuntu にしましょう.
続いてバージョンを聞かれますが focal にします.

Welcome - Visual Studio Code 1_3_2021 12_08_02 PM (2).png

これでひとまずリポジトリに紐づいたコンテナを作ることができました.
ここからは C++ や Python が実行できるようにコンテナの設定を整えていきます.

コンテナの設定

初めてコンテナが作られたときは以下のようなディレクトリ構成になっていると思います.
ここから設定ファイルを編集したり,新しく設定ファイルを追加したりしていきます.

/workspaces/<repo-name>
├── .devcontainer
│   ├── devcontainer.json
│   └── Dockerfile
├── .git
└── README.md

最終的なディレクトリ構成はこんな感じです.

/workspaces/<repo-name>
├── .clang-format
├── .devcontainer
│   ├── devcontainer.json
│   └── Dockerfile
├── .git
├── .gitignore
├── README.md
└── requirements.txt

.gitignore の作成

リポジトリのディレクトリ直下で touch .gitignore を実行して空のファイルを作っておきます.
gitignore.iovscodeC++Python を入力して Create をクリックします.
表示された内容を全部先ほど作成した .gitignore にコピーして完成です.
必要があれば編集してください.

Dockerfile の編集

Dockerfile の # [Optional] Uncomment this ... 以下の部分に,コンテナが作られるときに実行されるコマンドを追加していきます.
apt-get でインストールする build-essential は C++ のコンパイラ g++ が入っていて,clang-format は C++ ファイルのフォーマット用です.
また,デフォルトでは Python 3.8.2 が入っていますが,Python のパッケージインストーラ pip が入っていないので python3-pip をインストールします.

# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.154.0/containers/ubuntu/.devcontainer/base.Dockerfile

# [Choice] Ubuntu version: bionic, focal
ARG VARIANT="focal"
FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}

# [Optional] Uncomment this section to install additional OS packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
    && apt-get -y install --no-install-recommends \
    build-essential \
    clang-format \
    python3-pip

.clang-format の作成

C++ ファイルのフォーマットの設定ファイルとして .clang-format を用意します.
VSCode のオートフォーマットを on にして C++ のフォーマッターを Clang-Format に設定することで,.clang-format の設定通り自動的にコードをフォーマットできます.
設定できる項目はめっちゃいっぱいある( https://clang.llvm.org/docs/ClangFormatStyleOptions.html )のでお好みで.
自分は正直よくわかってないのでとりあえず気になったものだけ設定しています.

ColumnLimit: 110
AllowShortBlocksOnASingleLine: true
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: true
BinPackArguments: false
BinPackParameters: false
BreakBeforeBinaryOperators: NonAssignment
ConstructorInitializerAllOnOneLineOrOnePerLine: true
IndentWidth: 2

requirements.txt の作成

requirements.txt は Python のパッケージ管理に使うファイルです.
ここにパッケージを列挙しておき,pip3 install -r requirements.txt を実行することで必要なパッケージを 1 コマンドでインストールすることができます.
導入するのは次のパッケージです.

パッケージ 説明
numpy 行列演算・数値計算とか用
flake8 リンター
autopep8 フォーマッター

これらを pip3 install でインストールしたあと,インストールしたパッケージの一覧を pip3 freeze で requirements.txt に書き出します.

$ pwd
/workspaces/<repo-name>
$ pip3 install numpy flake8 autopep8
$ pip3 freeze > requirements.txt

依存しているパッケージも合わせると requirements.txt は次のようになっていると思います.

requirements.txt
autopep8==1.5.4
flake8==3.8.4
mccabe==0.6.1
numpy==1.19.4
pycodestyle==2.6.0
pyflakes==2.2.0
toml==0.10.2

devcontainer.json の編集

コンテナの設定ファイルです.
この中に VSCode の設定やコンテナが作られたあとのコマンドなどを書いておくことで,コンテナを作成したとき設定が自動的に反映されます.

オプション 説明
settings コンテナ独自の VSCode の設定
extensions コンテナで使う VSCode の拡張機能
postCreatedCommand コンテナが作られたあとに実行したいコマンド

settings

VSCode の設定を書く部分です.

オプション 説明
editor.formatOnSave true でファイル保存時に自動フォーマット
python.languageServer Python IntelliCode のサーバ
python.pythonPath 使用する Python インタプリタのパス
python.linting.flake8Args flake8 の引数
python.formatting.provider Python のフォーマッタを選択
[cpp]->editor.tabSize C++ ファイルでのインデントの文字数
[cpp]->editor.defaultFormatter C++ のフォーマッタを選択

extensions

インストールしたい VSCode の拡張機能を列挙するところです.
自分はとりあえず以下のものを書いています.

拡張機能 ID 説明
Visual Studio IntelliCode visualstudioexptteam.vscodeintellicode AI アシスタントがコード補完を提示してくれる
C/C++ ms-vscode.cpptools C++ 用
Clang-Format xaver.clang-format C++ ファイル用フォーマッタ
Git Extension Pack donjayamanne.git-extension-pack Git 用
Python ms-python.python Python 用
Pylance ms-python.vscode-pylance Python 用
Bracket Pair Colorizer 2 coenraads.bracket-pair-colorizer-2 対応する括弧をカラーリングしてくれる
Trailing Spaces shardulm94.trailing-spaces 余分なスペースをハイライト・除去
Vim vscodevim.vim VSCode 用 Vim エミュレータ

postCreateCommand

コンテナ作成後に実行されるコマンドを書くところです.
pip3 install -r requirements.txt をここに書いておくことで,先ほど書いた requirements.txt のパッケージを自動的にインストールしてくれます.

remoteUser

root でコンテナに接続したいときは以下のようにコメントアウトします.
パーミッションまわりがいろいろ面倒なので自分は基本 root で使っています.

// "remoteUser": "vscode"

これらを設定すると devcontainer.json はこんな感じになります.

// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.154.0/containers/ubuntu
{
    "name": "Ubuntu",
    "build": {
        "dockerfile": "Dockerfile",
        // Update 'VARIANT' to pick an Ubuntu version: focal, bionic
        "args": {
            "VARIANT": "focal"
        }
    },
    // Set *default* container specific settings.json values on container create.
    "settings": {
        "terminal.integrated.shell.linux": "/bin/bash",
        "editor.formatOnSave": true,
        "python.languageServer": "Pylance",
        "python.pythonPath": "/usr/bin/python3",
        "python.linting.flake8Args": [
            "--max-line-length", // 1 行あたりの文字数を 110 に設定
            "110"
        ],
        "python.formatting.provider": "autopep8",
        "python.formatting.autopep8Args": [
            "--max-line-length", // 1 行あたりの文字数を 110 に設定
            "110"
        ],
        "[cpp]": {
            "editor.tabSize": 2,
            "editor.defaultFormatter": "xaver.clang-format" // 拡張機能 Clang-Format を選択
        },
    },
    // Add the IDs of extensions you want installed when the container is created.
    "extensions": [
        "visualstudioexptteam.vscodeintellicode",
        "ms-vscode.cpptools",
        "xaver.clang-format",
        "donjayamanne.git-extension-pack",
        "ms-python.python",
        "ms-python.vscode-pylance",
        "coenraads.bracket-pair-colorizer-2",
        "shardulm94.trailing-spaces",
        "vscodevim.vim"
    ],
    // Use 'forwardPorts' to make a list of ports inside the container available locally.
    // "forwardPorts": [],

    // Use 'postCreateCommand' to run commands after the container is created.
    "postCreateCommand": "pip3 install -r requirements.txt",

    // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
    // "remoteUser": "vscode"
}

以上でコンテナの設定は完了です.

コンテナのリビルド

仕上げとして,設定に基づいてコンテナをリビルドします.
左下の緑色の Dev Container: Ubuntu をクリックし,Remote-Containers: Rebuild Container を選択します.

devcontainer.json - algo-training-sample [Dev Container_ Ubuntu] - Visual Studio Code 1_3_2021 5_20_06 PM_LI.jpg

これで C++ と Python の実行環境ができました.
リビルドが完了したあと,例えば次の hello.cpp,hello.py をコンテナ内で実行できます.

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

int main() {
  cout << "I'm C++!" << endl;
}
# g++ -o hello hello.cpp
# ./hello 
I'm C++!
hello.py
print("I'm Python!!")
# python3 hello.py
I'm Python!!

あとはこれをリモートのリポジトリにプッシュしておけば,同じ環境をすぐに作ることができます.

C++ Standard の設定

入れたままだと拡張機能 C/C++ が C++ 17 の文法を書くとエラーメッセージが表示されてしまうので,C++ Standard の設定をします.
Ctrl + Shift + P でコマンドパレットを開き,C/C++: Edit Configurations (JSON) を選択します.

hello.cpp - algo-training-sample [Dev Container_ Ubuntu] - Visual Studio Code 1_10_2021 11_45_26 PM_LI.jpg

すると,/workspaces 直下にディレクトリ .vscode が作られ,その中に c_cpp_properties.json が作られます.
この中の cppStandard"gnu++17" に設定します.

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

例えば構造化束縛を使った以下のコードでもエラーメッセージが表示されなくなります.

hello.cpp - algo-training-sample [Dev Container_ Ubuntu] - Visual Studio Code 1_11_2021 12_01_38 AM.png

おまけ

自分は新しくディレクトリを作るとき C++ と Python のディレクトリを分けたいので,テンプレートとして次のディレクトリをリポジトリに入れています.

template
├── cpp
│   ├── build         // C++ の実行ファイル置き場
│   │   └── .gitkeep
│   ├── .gitkeep
│   └── run.sh        // C++ ファイル実行用スクリプト
└── python
    └── .gitkeep
run.sh
f=`echo $1 | sed -e 's/\(.*\).cpp/\1/'`
current_dir=$(eval pwd)
g++ -std=c++17 -g -o ${current_dir}/build/${f}.out $1
eval ${current_dir}/build/${f}.out

run.sh は C++ ファイルをコンパイル + 実行するスクリプトで, sh run.sh A.cpp みたいに使います.
競プロをやっていく上でもっといい運用方法があればぜひ教えてほしいです!

73
109
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
73
109