【これからプログラミングを始める人へ】WSL2+Docker+VScodeを使ってハンズオンで開発環境を構築しよう！

---
### １．はじめに

はじめまして！記事をご覧いただきありがとうございます、執筆者のシオンです。
「これからプログラミングを初めてみたい！」と思っている入門者の方にとって、
プログラミング環境の構築は最初の大きな障壁となるかもしれません。
本記事は、そのような方が少しでもスムーズにプログラミングに臨めるよう、
微力ながらお手伝いさせていただこうと思い執筆しました。

筆者自身、まだまだ勉強中の身ではありますが、少しでも多くの方にとって有益となる記事を目指しましたので、ぜひ肩の力を抜いて興味のある箇所から読んでいただければと思います。

なお、WSL2＋Docker の環境をすでに整えていて、最短でコーディングを始めたいという場合は、[このステップ](#4-3dockerとの連携) から始めていただいても問題ありません。

---

### ２．本記事が想定する読者

* **「細かいことはいいから、とにかく早く環境構築をクリアしたい」と思っている人**
※記事中のコード等をコピペしていただくだけでも動くと思います。

* **WSL2**や**Docker**など、比較的新しい技術がどんなものか触ってみたい人

---

### 3．筆者の環境と、今回使用するソフトウェア類について

* システム
  
  * OS 
    
    * ホストOS : **Windows 11** Pro 21H2（ビルド : 22000.856）
    
    * ゲストOS : **Ubuntu 20.04**.4 LTS
  
  * CPU : 12th Gen Intel(R) Core(TM) i7-12700K 
  
  * GPU : NVIDIA GeForce RTX 3080 Ti
  
  * RAM :  32GB

* ソフトウェア類
  
  * Visual Studio Code (以下VScode)
  
  * Windows Subsystem for Linux (以下WSL2)
  
  * Docker for Desktop 4.11.1 (84025) 
    
---

### ４．では、始めましょう！

::: note warn

注意！
本記事では、システム仕様についての厳密性や機密性よりも「わかりやすさ」を重視しているため、構築環境はほぼ必要最低限の構成となっています。より充実した環境・セキュアな環境を作りたい方は、別途個人でのカスタマイズをお願いします。

:::

今回の環境構築では、Windowsの機能であるWSL2とDocker for Desktopが提供するコンテナ仮想化を利用して、以下の言語に対応したリモート開発環境を整えます。

**なお、この記事では環境構築の簡略化のため、Docker公式が推奨するDocker本来の使い方を一部無視しています。** （「少し詳しい話」をご覧ください。）

 <details><summary><strong>なぜDockerを使うのか？</strong>(読み飛ばし可)</summary>

Dockerを使わずとも、Windows上に直接プログラミング環境を構築することは可能です。
そして、Dockerを利用しないのであればWSL2の導入も必要ありません。
では、なぜわざわざDockerとWSL2を導入する手順を紹介するのかというと、
Dockerを活用することで以下のようなメリットを享受することができるからです。
 * <strong>ホストをクリーンな状態に保つことができる。</strong>
    ホストOSと隔絶された仮想コンテナ内に開発に必要なシステムやツールを導入するので
    自分が普段使うための開発環境を汚さずに済みます。
    例えば、普段とは異なるバージョンやライブラリを用いて、Pythonで開発をする場合を想定します。バージョン管理ツール [pyenv](https://github.com/pyenv/pyenv) などの利用も有効ですが、頻繁に異なるランタイム間を行き来するのは大変です。また、最悪の場合 **普段使いのPython環境で誤った操作をしてしまい、ライブラリの依存関係や競合などが原因で環境が壊れてしまった…** などということも考えられます。
    **Dockerを使えばそのような懸念から解放されます！** 複数のランタイムをコンテナごとに隔離して運用することも可能ですし、そもそもホストOSとは異なるOS上での開発も可能になります。開発環境と本番環境が異なるOS同士といった場合にも、Dockerを導入すれば解決です。

 * <strong>コンテナは扱いやすく再現性も高いので、チーム内で開発環境を統一しやすい</strong>
    この後もう少し詳しく扱いますが、Dockerコンテナは基本的にDockerfileという設定ファイルに基づいて作成されます。このファイルにはコンテナのベースとなるイメージファイルの指定や、コンテナの作成（ビルド）の際に実行されるコマンドなどを記述します。
    このDockerfileの存在が、Dockerの大きな利点である再現性と運用性を支えています。Dockerfileをチーム内で共有すれば、理論上ほぼ同一の環境で複数人が開発を行うことができます。そして、必要なくなった環境を破棄することも、コンテナを削除すればよいだけなので簡単です。便利ですよね！
    
　
</details>

<details><summary>少し詳しい話(読み飛ばし可)</summary>具体的には「個人開発で完結し、別途WEBサーバーソフトウェア（Nginx,Apacheなど）やRDBMS（MySQLなど）の導入をしない」といった利用を想定していますので、コンテナごとにプロセスを分離してDocker-composeで複数コンテナを同時起動することなどはしません。<br>これは、Docker公式ドキュメント <a href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#decouple-applications"><strong>Best practices for writing Dockerfiles</strong></a> でも言及されている

> Each container should have only one concern.
>（各コンテナは、それぞれただ１つの役割のみを担うべきである。）

といった原則に反していると言えるでしょう。
とは言ったものの、Dockerの恩恵すべてを捨てているわけではありません。
Dockerfileを保管しておけば、環境を再構築したり共有したりする手間はホスト上に直接環境を構築する場合よりも少ないですし、後々発展的な開発する時にもDockerfileを編集することで、選択的に必要なツールやランタイムを導入できます。
</details>

:::note info 
**今回は難しいことは考えず、色々な言語の開発環境が１つにまとまった「欲張りセット」を作ってみます。**
:::



#### 本記事で扱うプログラミング言語
  
  * Python
  
  * C／C++
  
  * Java
  
  * Rust
  
本記事をご覧の方の中には、競技プログラミングを始めるためにプログラミング環境を整えたいとお考えの方も多いと思います。
そのため、世界的にもシェアが高く競プロでも主流の**C系とPythonについてはすぐにコーディングができるようにしています。**
しかし、**導入の複雑さなどからJavaとRustに関しては、もうひと手間セットアップが必要です。予めご了承ください。**

#### 4-1.WSL2とDockerの導入
WSL1とWSL2はそれぞれ仕様に違いがあります。今回はWSL2のほうを使います。
従来は導入が大変なWSL2でしたが、最近はとても簡単に有効化できるようになっています。
詳しくは[Microsoftの公式ページ](https://docs.microsoft.com/ja-jp/windows/wsl/install)を参照してください。
管理者権限でPowerShellを起動し、以下のコマンドを実行しWindowsを再起動すれば標準で**Ubuntu**がインストールされます[^1]。
```PowerShell:PowerShell（管理者権限で実行）
wsl --install
```
:::note info
余談
このLinuxの種類（ディストリビューション）は他のものも選択でき[^2]、筆者はUbuntuの他にペネトレーションテストに特化したKali Linuxを導入しています。Windows11ではWSLg[^3]と呼ばれる機能を使うことで、Windows10よりも簡単にLinuxマシンをGUIで操作できます！**すなわち、Linuxのアプリを疑似的なWindowsアプリとして実行できるということです！すごい！**
:::

再起動するとUbuntuのコンソールが自動的に起動し、ユーザー設定を促してくると思います。
画面の指示に従って初期設定を行ってください。この際、自動的に立ち上がらなければ、「検索」からUbuntuと調べていただくとアプリがヒットすると思いますので、それを実行してください。
ここで、高機能な統合ターミナルである **Windows Terminal** をインストールしておくことを強くお勧めします。Windows11では標準で実装されていますが、Windows10では自分でインストールする必要があります。これも[Microsoftの公式ページ](https://docs.microsoft.com/ja-jp/windows/terminal/install)を参照していただければと思います。

<details><summary><strong>公式ドキュメントのススメ　～まずは公式資料を参照しよう！</strong></summary>

少々本題とそれますが、筆者はトラブルやエラーに遭遇した際の汎用的な解決方針として
***「困ったら公式ドキュメントを調べる」*** ことが、初歩的ながら盲点でもある、とても有効な手法だと考えています。
英語だけのドキュメントなどもあり、気が滅入ることもあるかと思いますが、「何時間も調べてわからなかったことが実は公式資料に書いてあった」ということも稀にあります。
困った際には、ぜひ公式ドキュメントに記載がないか調べてみてください！

</details>

これで、WSL2の導入は完了です。一応、アップデートをしておきましょう。
```bash:Ubuntu
sudo apt update
sudo apt upgrade
```
次いてDockerの導入です。必ずWSL2の導入後に、以下のステップに進んでください。
[ここから](https://desktop.docker.com/win/main/amd64/Docker%20Desktop%20Installer.exe?utm_source=docker&utm_medium=webreferral&utm_campaign=dd-smartbutton&utm_location=header) Docker for Desktop のインストーラーがダウンロードできるので、ダウンロード後に実行して下さい。**※この際、「Install required Windows components for WSL2」 に忘れずにチェックを入れてください。これをしないと、WSL2との連携がうまくいきません。また、Dockerは必ずWindows側に導入して下さい。**
- [ ]  Install required Windows components for WSL2
   ↓
- [x]  Install required Windows components for WSL2

念のため、Windows Terminal からUbuntuのターミナルとPowerShellを開いて、
両方のシェルで `docker -v` というコマンドを実行しましょう。
返ってきたバージョン情報が一致していればOKです。

これで WSL2+Docker の環境が整いました！

#### 4-2.VScodeと拡張機能の導入
さて、[4-1](#4-1wsl2とdockerの導入) にてWSL2とDockerの導入と基本設定は完了しました。
ここでは、プログラミングをしていく上で非常に重要なツールとなるテキストエディタを
導入していきましょう。
ここでは、Microsoft社が無償で配布している [Visual Studio Code（VScode）](https://code.visualstudio.com/docs/?dv=win)を利用します。
上のリンクを押すと自動的にインストーラーがダウンロードされます。
インストール時の設定は、デフォルトのままで問題ありません。
初めてVScodeを立ち上げた場合、まずは日本語化の設定を済ませてしまいましょう。
画面左側の「アクティビティバー」から拡張機能を開き、検索欄にJapaneseと入力すると、
検索結果の一番上にMicrosoft公式の拡張機能 ***Japanese Language Pack for Visual Studio Code*** があると思います。
これをインストールしてVScodeを再起動すれば、インターフェースの日本語化は完了です。

<details><summary>テキストエディタについて</summary>

コード入力の補完や正規表現を使った検索・置換などの高度な機能を提供してくれるテキストエディタは、実際にコードを書く上で最も作業効率に直結する要素です。
有名なテキストエディタとしては、VScodeの他にもVimやAtomなどがあります。VScodeと似たようなものとして、同じくMicrosoft社が提供している Visual Studio がありますが、こちらは統合開発環境（IDE）とよばれ VScode に比べ標準機能が充実している代わりにマシン負荷が大きく、本格的な開発業務向きと言えるでしょう。
VScodeの大きな魅力として動作が軽量である点と、拡張機能が充実しているという点が挙げられます。主要な言語ならば、まず間違いなくVScodeでの実行・デバッグが可能です。エディタ選択は個人の好みや慣れが大きく影響しますので[^4]、必ずしもVScodeを使う必要はありませんが、モダンかつ高機能なエディタとしてVScodeは非常におすすめです。
ショートカットを使いこなせば、コーディングも爆速になると思います！
[@Takahiro Ito様の記事がとても参考になります](https://qiita.com/TakahiRoyte/items/cdab6fca64da386a690b)

</details>

##### 続いて、VScodeとWSL2の紐づけを行っていきます。
ここで、最も重要な拡張機能を導入します。
日本語化のときと同様に、拡張機能から ***Remote Development*** をインストールします。
この拡張パックには３つの拡張機能が含まれており、これによってリモートSSH接続やWSL2内のフォルダーにシームレスにアクセスすることが可能になります。

では、実際にVScodeからUbuntu内のデータにアクセスしてみましょう。
VScodeを起動すると、画面左下にリモートウィンドウを開くアイコンが追加されています。
ここをクリックして、**WSLでフォルダーを開く**を選択しましょう。
![VScode説明.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618913/4cbf44d6-1f1e-ade3-2c5c-39fb39474fdc.jpeg)
筆者は、***\\wsl$\Ubuntu\home\\*****{ユーザー名}*****\workspace*** に作業フォルダーをまとめています。
これでVScodeとWSL2の連携は完了です。
試しに、VScodeでフォルダー内に test.txt を作成して内容を編集してみます。
リアルタイムで、Ubuntu内のデータをWindowsのVScode側から編集できていることが確認できると思います。
![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618913/d6806ce6-cdba-ad9f-0879-16394bd0f6f9.gif)
ここまでの設定を済ませてしまえば、今後の環境構築は格段に楽になると思います。
残るは、Dockerを使ったコンテナの作成とVScodeからコンテナへの接続設定だけです！

#### 4-3.Dockerとの連携

ここまでのセットアップ、お疲れさまでした！
いよいよ最後のステップとなる、VScodeとDockerの連携です。
Dockerコンテナを利用した開発の内部構造は、少々複雑なものとなっています。
詳しく知りたい方は、お手数ですが[公式ドキュメント](https://code.visualstudio.com/docs/remote/containers)をご参照ください。

[**４**](#４では始めましょう)冒頭の **なぜDockerを使うのか？** でも触れましたが、Dockerコンテナは基本的に***Dockerfile***[^5]という設定ファイルの記述に基づいて構築されます。**このファイルを一度作成すれば、何度でも同じ環境を様々なプラットフォーム上に爆速で構築できます！** これがDockerの大きな恩恵の１つです。

そしてVScodeを使うともっと嬉しいことがあります。
それは、***Remote Development*** のおかげでDockerのコマンドや仕組みに詳しくなくとも、
VScode側が自動でコンテナのビルド（構築）をすべてやってくれることです。
ここでは***devcontainer.json***というファイルも追加で作成しますが、Dockerfileさえあれば、最低限の環境は作れます。[^6]

早速はじめましょう！
先程Ubuntu上に作った作業フォルダー内に、以下のようにフォルダーとファイルを作ってください。

```bash:作業フォルダーの構成
.（作業フォルダー）
├─ .devcontainer
│   ├── Dockerfile
│   └── devcontainer.json
```

.devcontainer.json の **’ . ’** と Dockerfile の最初が大文字になっている点に注意してください。
Dockerfile と devcontainer.json はVScodeがコンテナを作る上で設計図となるものであり、
その書き方にはいろいろなルールや作法があります。この点も、詳しく知りたい方は調べてみてください。
今回は入門的な記事なので、細かい話は割愛します。
とりあえず、以下の内容をコピペしてそれぞれのファイルを編集してください。

```dockerfile:Dockerfile
#ここではベースイメージという、構築する環境の基礎となるイメージをDockerHubなどから選び記述します。
#今回は、Ubuntuイメージを使用します
ARG VARIANT="hirsute"
FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}


#作成する環境の時間設定を日本時間にしておきます。これにより、ビルドが中断されなくなります。
ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

#日本語化の設定
RUN apt update && apt install -y language-pack-ja  g++
RUN update-locale LANG=ja_JP.UTF-8

ENV LANG="ja_JP.UTF-8" \ 
    LANGUAGE="ja_JP:ja" \ 
    LC_ALL="ja_JP.UTF-8" \ 
    LC_ALL="ja_JP.UTF-8" \ 
    TZ="JST-9" \ 
    TERM="xterm"

CMD ["bash"]
```

```json:devcontainer.json
{
	"name": "Ubuntu",
	"build": {
		"dockerfile": "Dockerfile",
		"args": { 
			"VARIANT": "focal"
		}
	},
	
	// 追加する拡張機能のIDを入力
	"extensions": [

		//Javaを使うひとはアンコメントして有効化
		//"vscjava.vscode-java-pack",
		
		//Rustを使う人はアンコメントして有効化
        //"Swellaby.rust-pack",
		
		"formulahendry.code-runner",
		"ms-vscode.cpptools-extension-pack",
		"ms-python.python"
	],

	// コンテナのフォワードポートの設定
	"forwardPorts": [900],

	// この設定をしないと、コンテナのデフォルトユーザーがrootとなり不都合が多いので必須。
	// non-root user などで調べるとより詳しくわかります。
	"remoteUser": "vscode",

	// 追加導入する機能の選択
	"features": {
		"docker-from-docker": "latest",
		"git": "latest",
		"sshd": "latest",
		"python": "latest"
	}
}
```

ファイル編集が完了したら、WSLに接続した時と同様に画面左下のアイコンをクリックし、「リモートウィンドウを開くオプション」の選択一覧から **「コンテナーのリビルド」** を選んでください。そうすると、自動的にVScodeがコンテナのビルドを開始します。今回使うDockerfileはレイヤーも多く、複雑性が増すような最適化の作業を行なっていないのでビルドにかなりの時間を要します。（筆者の環境でも約10分ほどかかりました）
コーヒーでも飲んでビルドの完了を待ちましょう♪

さて、ビルドは完了しましたでしょうか？
無事に完了した皆さん、どうもお疲れさまでした！
今回使用したベースイメージ自体、元々ツール類が豊富にプリインストールされているものだったので、一般的なコンテナビルドよりも時間がかかってしまいました。
しかし、皆さんが今後自分でコンテナを作成するときは、ここまでの時間はかからずよりスムーズに作業ができると思います。

さて、これでPythonとC/C++のコーディング環境は整いました。
それらの開発環境が整っているかは、以下のコマンドをターミナルに入力して確認できます。
```bash:VScodeのターミナル
python -V   # -> Python 3.10.6
gcc         # ->（略）~ gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) 
g++         # -> gccと同様
```

大雑把に言えば、python が文字通り Python のランタイムを、gcc と g++ がそれぞれ C と C++ の開発環境を提供しています。
Dockerfileにより、これら言語に対応する拡張機能はインストール済みなので、あとはデバッグの設定をすれば`F5`キーで実行とデバッグが可能になります。
しかし、このような面倒な設定なしでも、プログラムの実行やコンパイル等を行うだけならばVScodeの拡張機能で可能です。
それが***Code Runner***です。この拡張機能は非常に多くの言語に対応しており、面倒な設定なしに選択範囲のコードを実行することができるという、まさに**神**拡張機能ともいうべき存在となっています。
**「プログラムの実行とコンパイルさえできれば十分」という方は、ここで全ての設定が完了したと言えるでしょう！**
動作中の変数の中身やメモリの使用状況などの確認といった、いわゆるデバッグ機能も利用される方は、あと少し設定項目があります。以下の折り畳みテキストをご参照ください。 

<details><summary><strong>デバッグ機能を使うための設定</strong></summary>

作業フォルダーの中に、`.vscode` フォルダーを作成し、以下のような構成にしてください。
```bash:作業フォルダー
.
├── .devcontainer
│   ├── Dockerfile
│   └── devcontainer.json
├── .vscode
│   ├── c_cpp_properties.json
│   ├── launch.json
│   ├── settings.json
│   └── tasks.json
```
あとは、それぞれのファイルをこのように編集して下さい。（コピペOKです）
```json:c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "/usr/include/c++/9",
                "/usr/include/x86_64-linux-gnu/c++/9"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "clang-x64"
        }
    ],
    "version": 4
}
```

```json:launch.json
{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        },
        {
            "name": "g++ - アクティブ ファイルのビルドとデバッグ",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/${fileBasenameNoExtension}",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "internalConsoleOptions": "openOnSessionStart",
            "setupCommands": [
                {
                    "description": "gdb の再フォーマットを有効にする",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "C/C++: g++ アクティブなファイルのビルド",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}
```

```json:settings.json
{
    "terminal.integrated.defaultProfile.linux": "zsh",
    "[c]": {
      "editor.defaultFormatter": "ms-vscode.cpptools"
    },
    "[cpp]": {
      "editor.wordBasedSuggestions": false,
      "editor.suggest.insertMode": "replace",
      "editor.semanticHighlighting.enabled": true,
      "editor.defaultFormatter": "ms-vscode.cpptools"
    },
    //フォーマッターにblackを利用
    "python.formatting.blackPath": "/usr/local/py-utils/bin/black",
    "python.formatting.provider": "black",
    "[python]": {
      "editor.formatOnPaste": false,
      "editor.defaultFormatter": null,
      "editor.formatOnSave": true
    },
    "files.autoSave": "afterDelay",
    "code-runner.executorMap": {
      "javascript": "node",
      "java": "cd $dir && javac $fileName && java $fileNameWithoutExt",
      "c": "cd $dir && gcc $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
      "cpp": "cd $dir && g++ $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
      "objective-c": "cd $dir && gcc -framework Cocoa $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
      "php": "php",
      "python": "python -u",
      "perl": "perl",
      "perl6": "perl6",
      "ruby": "ruby",
      "go": "go run",
      "lua": "lua",
      "groovy": "groovy",
      "powershell": "powershell -ExecutionPolicy ByPass -File",
      "bat": "cmd /c",
      "shellscript": "bash",
      "fsharp": "fsi",
      "csharp": "scriptcs",
      "vbscript": "cscript //Nologo",
      "typescript": "ts-node",
      "coffeescript": "coffee",
      "scala": "scala",
      "swift": "swift",
      "julia": "julia",
      "crystal": "crystal",
      "ocaml": "ocaml",
      "r": "Rscript",
      "applescript": "osascript",
      "clojure": "lein exec",
      "haxe": "haxe --cwd $dirWithoutTrailingSlash --run $fileNameWithoutExt",
      "rust": "cd $dir && rustc $fileName && $dir$fileNameWithoutExt",
      "racket": "racket",
      "scheme": "csi -script",
      "ahk": "autohotkey",
      "autoit": "autoit3",
      "dart": "dart",
      "pascal": "cd $dir && fpc $fileName && $dir$fileNameWithoutExt",
      "d": "cd $dir && dmd $fileName && $dir$fileNameWithoutExt",
      "haskell": "runhaskell",
      "nim": "nim compile --verbosity:0 --hints:off --run",
      "lisp": "sbcl --script",
      "kit": "kitc --run",
      "v": "v run",
      "sass": "sass --style expanded",
      "scss": "scss --style expanded",
      "less": "cd $dir && lessc $fileName $fileNameWithoutExt.css",
      "FortranFreeForm": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
      "fortran-modern": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
      "fortran_fixed-form": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
      "fortran": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt"
    },
    "code-runner.runInTerminal": true,
    "files.associations": {
      "iostream": "cpp",
      "cmath": "cpp",
      "*.tcc": "cpp",
      "map": "cpp"
    },
    "files.autoGuessEncoding": true,
    "C_Cpp.errorSquiggles": "Disabled"
}
```

```json:tasks.json
{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "cppbuild",
      "label": "C/C++: g++ アクティブなファイルのビルド",
      "command": "/usr/bin/g++",
      "args": [
        "-fdiagnostics-color=always",
        "-g3",
        "${file}",
        "-o",
        "${fileDirname}/${fileBasenameNoExtension}"
      ],
      "options": {
        "cwd": "${fileDirname}"
      },
      "problemMatcher": ["$gcc"],
      "group": "build",
      "detail": "コンパイラ: /usr/bin/g++"
    }
  ]
}
```



これで、C／C++とPythonに関してはF5キーを押して実行とデバッグができるようになりました！

</details>

それでは、実際に***Code Runner***を使ってC++とPythonのプログラムを実行してみます。
以下はどちらも、 ”与えられた整数値N以下までの[フィボナッチ数列](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%9C%E3%83%8A%E3%83%83%E3%83%81%E6%95%B0)を出力するプログラム”　です。

```cpp:fibonacci.cpp
#include <iostream>
using namespace std;

int main()
{
    int N;
    int fib1 = 0, fib2 = 1, fib3 = 1;
    cin >> N;

    cout << "The Fibonacci Series is follows : " << endl
         << fib1 << " " << fib2 << " ";
    
    while (fib1 + fib2 <= N)
    {
        fib3 = fib1 + fib2;
        fib1 = fib2;
        fib2 = fib3;
        cout << fib3 << " ";
    }
    
    cout << endl;
    
    return 0;
}
```
![Animation2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618913/0ff8f5a7-8f64-3fce-3942-556afc6c7a6d.gif)

```python:fibonacci.py
def fibonacci(N: int):
    a, b = 0, 1
    while a < N:
        print(a, end=" ")
        a, b = b, a + b
        print()


N = int(input("Put the number..."))
fibonacci(N)
```
![Animation3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618913/f21961c7-5b45-8fcd-5259-2f76c8dd96aa.gif)

きちんと実行できていますね！ちなみに、ショートカットは `Ctrl + Alt + N` です。
これでようやく、C／C++とPythonのコーディング環境が整いました！
RustとJavaの環境が必要ない方は、本記事の内容はこれで完結です。本当にお疲れ様でした！

---

### ５．RustとJavaの環境構築について
それでは、本記事のラストとして[Rust](https://www.rust-lang.org/ja/)とJavaの環境を整えていきたいと思います。

##### まずはRustから
VScodeのターミナルで以下のコマンドを実行してください。

```bash:VScode
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

このコマンドだけで、Rustの開発に必要なビルドツールやパッケージマネージャがインストールできます。
途中で出てくるインストール方式の選択は、**1) Proceed with installation (default)** を選んでください。
インストール後、`rustc -V` `rustup -V` `cargo -V` などで導入が成功しているか確認できます。

ここからが先程の C系 や Python とは異なるのですが、そのまま作業フォルダーに **.rs** ファイルを作成しても拡張機能の***rust-analyzer***がうまく機能しません。これでは、コード補完やインテリセンスなどのVScodeの便利機能が使えません。
ここで、先程導入したCargoを使います。以下のコマンドで、新しくRust用のワークスペースを作成しましょう。

```zsh:VScode
cargo new (プロジェクト名)
```
このコマンドにより、新しいワークスペースが生成されます。
しかし、今回のように ***Cargo.toml*** が作業フォルダー直下にない場合、一度ウィンドウを再読み込みして ***rust-analzer*** にワークスペースを認識させる必要があります。
`F1`キーを押して `reload` と入力すると「ウィンドウの再読み込み」が出てくるのでこれを押しましょう。
すると、初期生成された main.rs の hello world プログラムの実行およびデバッグができるはずです。
![Animation4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618913/540c40ca-fa24-16b4-06f3-4a2214e81bb8.gif)

複数のプロジェクトを１つの作業フォルダーの中に作成したい場合、[**Cargo.toml を編集するというやり方**](https://paruma184.hatenablog.com/entry/2021/09/22/210945#AtCoder%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B%E3%82%AF%E3%83%AC%E3%83%BC%E3%83%88%E3%82%92Cargotoml%E3%81%AB%E6%8C%87%E5%AE%9A:~:text=%E7%B4%B9%E4%BB%8B%E3%81%97%E3%81%BE%E3%81%99%E3%80%82-,%E8%A4%87%E6%95%B0%E3%81%AE%E3%82%A8%E3%83%B3%E3%83%88%E3%83%AA%E3%83%BC%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%AE%E8%A8%AD%E5%AE%9A,-cargo%20new%20%E3%81%A7)[^7]もありますが、単純に新しいプロジェクトを Cargo で作成するごとにウィンドウを再読み込みするという方法で問題ないと思います。
これでRustの環境も完成です！

##### いよいよ最後！Javaです！
それでは、Javaの環境を整えましょう。Javaは本記事で紹介したC系言語に比べ、インストールするツールやパッケージなどがとても多いです。これは Java が **JVM（Java Virtual Machine）** という独自の仮想マシンを利用するためです。この JVM　の存在が、クロスプラットフォーム開発という Java の大きな魅力を支えています。

何はともあれ、導入していきましょう！
以下のコマンドを、上から順にVScodeのターミナルで実行してください。

```zsh:VScode
sudo apt update && sudo apt install default-jdk  　　　　　　　　　　　  # JDKのインストール
javac --version && java --version                 　　　　　　　　　　　 # javaの導入確認
sudo apt install maven                          　　　　　　　　　　　   # ツール群Mavenの導入
mvn -version                                  　　　　　　　　　　　     # Mavenの導入確認
cd /usr/lib/jvm                                 　　　　　　　　　　　   # JDKがあるフォルダーへ移動
ls                                                　　　　　　　　　　　 # -> java-11-openjdk-amd64 があるか確認
echo export JAVA_HOME=/usr/lib/jvm/java-version-xxx-jdk >> ~/.○○○rc    # お使いのシェルに合わせて変えてください。
echo 'export PATH="$PATH:$JAVA_HOME/bin"' >> ~/.○○○rc                  # .bashrc や .zshrc に記述しJDKのパスを通す
source ~/.zshrc  　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 # 変更の適用

!最後２つのコマンドは、「>」を１つのみで実行すると環境が壊れる可能性があります。十分にご注意ください。
```

なお、将来性を考えてMavenを導入しましたが、今回は使いません。
ではJavaプロジェクトを作成しましょう。
`F1`キーを押してコマンドパレットを開き、**「Create Java Project」** を選択して **No build tools** からワークスペースを置きたいディレクトリを指定し、プロジェクト名を入力します。新しいウィンドウが開きますのでそのまま編集することも可能ですし、元のウィンドウに戻って作業することもできます。
![Animation5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618913/f4d10f3b-247c-0197-844a-c0c06850d322.gif)

以上で全ての環境構築が完了しました！
ここまで読んでくださった皆さん、本当にありがとうございます！
そして、お疲れ様でした！
本記事が、これからの皆さんの快適なコーディングライフに少しでも貢献できたなら、これに勝る喜びはありません。
今後もぜひ、ご自身で試行錯誤し、**「自分の、自分による、自分のための環境」** を作ってみてください！

---

### ６．おわりに
改めまして、本記事を最後までご覧いただき、ありがとうございました！
今回が初執筆だったことや、最近になって念願だった初めてのデスクトップPCを手に入れてハイテンションだったためか、当初よりも大幅に文量の多い記事となってしまいました（笑）。書きたいことや自分が始めたてのころに悩んだこと・躓いたことなどをなるべく多く盛り込もうとしたところ、全体的に冗長な文章になってしまったことは今後の反省とします… (´·ω·`)
これからも、「有識者の方がご覧になっても卒倒しないレベル」の記事を目指し、ゆっくり更新していけたらと思いますのでよろしくお願いします！

[^1]:PowerShellを起動した際、アップデートを勧められるかもしれませんが、そのまま実行していただいて問題ありません。
[^2]:上述のコマンドに - d オプションをつけ、「-d Debian」のようにすればディストリビューションを指定できます。
[^3]:[Windows Subsystem for Linux GUI](https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps) (WSLg)
[^4]:しばしば推しのテキストエディタを巡る論争が勃発し、宗教戦争とも揶揄されます。([エディタ戦争](https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF%E6%88%A6%E4%BA%89))
[^5]:[Dockerfileについての説明（公式）](https://docs.docker.jp/engine/reference/builder.html)
[^6]:本文でも触れた通り、Docker-composeを利用した複数コンテナの結び付けは今回の記事では扱っていません。
[^7]:「ぱるまの日記」様　『AtCoder用にVSCodeを用いたRustの開発環境の構築をした話』より