VSCode (VSCodium) によるポータブルなC言語開発環境の構築

# 追記
## 2020年5月18日

2020年度版を投稿しました。
(https://qiita.com/TakekazuKATO/items/3e5f4802c9130fa34a75)

# はじめに
C言語のプログラミングの授業で使う開発環境を何にするか考えていて，行き着いたのがVSCode+mingw64をポータブルにするというものでした．
大学では学生はみんなノートパソコンを持っていてそこに開発環境をインストールさせるのですが，大学推奨パソコンのスペックがしょぼくて，学生のパソコンスキルも低いので，軽くてインストールが簡単な開発環境が必要でした．
大学では，Visual Studioは大学のサイトライセンスがあるんですが，重すぎてインストールすら数時間かかる上に起動にも時間がかかりすぎる．Eclipse+CDTも同様に重すぎる．CLionは比較的軽いんですが，アカウントの登録が必要，などなどどれも決め手に欠ける．
自分自身はVSCode+cpptools(+mingw64)という組み合わせを使用していて，動作が軽くて機能も十分で気に入っていましたが，これを学生にインストールさせるとなるとハードルが高くて二の足を踏んでいました．

そんな時[Portable Mode in Visual Studio Code](https://code.visualstudio.com/docs/editor/portable) というのを発見して，これなら拡張機能をインストールした状態で配布できるのではないかと思いつきました．その後，mingw64もポータブルにして配布ファイルに含めて，VSCodeのプロジェクトのテンプレートを作れる拡張機能を見つけて，授業用のカスタムポータブル開発環境として配布できるまでになりました．

# 条件
授業用の開発環境の条件は以下のようなものです．
1. インストールが簡単で学生自身が設定をいじる必要がない．
2. デバッガがGUIで動作する
3. コンパイル，実行が簡単
4. コード整形機能，コード補完機能がある
5. プロジェクトの作成が簡単で設定不要

このうち，２と４は，VSCodeのcpptoolsをインストールすればクリアできます．３に関してはCode Runnerを使えばできます．問題はVSCode+cpptoolsでは，設定はjsonファイルを編集する必要があり，またプロジェクト管理機能もないというものです．ここら辺の問題をプロジェクトのテンプレートを作るProject Template 拡張機能と，全てポータブルにするという方法で解決しました．

# ポータブル環境の構築
## VSCodiumのインストールとポータブルモード
VSCode自体はオープンソースですが，配布されているバイナリにはマイクロソフトのロゴなどが含まれていてこれが気になっていました．今回はカスタム環境を配布することが目的なのでバイナリで再配布できないと困るわけです．受講する学生だけにこっそりと配布するからいいかと思っていた時に [VSCodium](https://github.com/VSCodium/vscodium)のニュースを見て，これなら大丈夫そうということでこっちにしました．これは，基本的にVSCodeと同じものでロゴなどが独自のものになっています．

releasesを見ると各種OS向けのバイナリやインストーラが揃っています．今回はWindows向けでインストーラのないVSCodium-win32-x64-1.33.1.zipを選びました．これを好きなところに展開します．

ポータブルモードで起動するには展開したフォルダ直下にdataというフォルダを作成しておけば拡張機能や設定ファイルはここに置かれるようになります．プログラムの起動はVSCodium.exeをダブルクリックすればVSCodiumが起動します．
フォルダ構成は以下のようにしておきます．

```
CPrograming/
         |- VSCoduim/      このフォルダ作成しておいて，その下にVSCodiumを展開
                 |- data/  VSCodiumの展開後に，このフォルダを自分で作成する
                 ：
                 └ VSCodium.exe
```     

## MinGW-w64のインストール
通常はmsys2やcygwinなどと一緒にインストールしますが，ここではgcc(g++)，gdbとmakeだけあればいいので，mingw-w64だけをインストールします．また，インストーラも使用せずコンパイル済みバイナリを直接展開します．コンパイル済みバイナリは[https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/](ここ)にあるので，この中からずーと下にスクロールして[x86_64-posix-sjlj](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/8.1.0/threads-posix/sjlj/x86_64-8.1.0-release-posix-sjlj-rt_v6-rev0.7z/download)(クリックすると直接ダウンロード)を選びます．このファイルを上記のCProgramingのフォルダの下に展開します．フォルダ構成は次のようになっています．

```
CPrograming/
         |- mingw64/
         |- VSCoduim/      
                 |- data/  
                 ：
                 └ VSCodium.exe
```

## 起動スクリプトの作成
ここで問題となるのが，mingw64の実行パスです．ポータブル環境なのでユーザがどこに展開するかわからないので，実行パスを相対的に指定する必要があります．そこで，起動スクリプトを用意しておいて，そこでパスを指定してVSCodiumを起動することにします．CPrograming直下にStart.cmdというファイルを作成して，その中身を以下のようにします．

```Start.cmd
@echo off
set MINGW=%~dp0mingw64\
set PATH=%~dp0mingw64\bin;%PATH%
start %~dp0VSCodium\VSCodium.exe
```

%~dp0というのふぁスクリプトをおいてあるパス名に展開されるので，これでmingw64のコマンドにパスが通ります．またついでにmingw64をインストールパスをMINGWという環境変数で記憶しておきます．

```
CPrograming/
         |- mingw64/
         |- VSCoduim/      
                 |- data/  
                 ：
                 └ VSCodium.exe
         └ Start.cmd
```

このStart.cmdをダブルクリックすればパスを設定した上で開発環境が立ち上がります．

## 拡張機能のインストール
ここでVSCodiumで必要な拡張機能をインストールします．使用した拡張機能は以下のものです．

- C/C++ (ms-vscode.cpptools)
  - コード補完，コード整形
- Code Runner (formulahendry.code-runner)
  - 簡易実行（コンパイル，実行）
- Japanese Language Pack for Visual Studio Code (ms-ceintl.vscode-language-pack-ja)
  - 日本語パック
- Project Templates (cantonios.project-templates)
  - テンプレートプロジェクトの作成，テンプレートからプロジェクトを作成
- zenkaku (cantonios.project-templates)
  - 全角スペースが見えるようになる

## 設定
VSCodiumの設定をします．設定ファイルは以下にあります．

```
CPrograming/
         |- mingw64/
         |- VSCoduim/      
                 |- data/
                      |- user-data/
                             |- User/
                                   ：
                                   └ settings.json 設定ファイル
                 ：
                 └ VSCodium.exe
         └ Start.cmd
```

settings.jsonの中身を以下のようにします．VSCodiumからメニューの設定を選んでもいいですが，上記のsettings.jsonを直接置き換えてもいいです．

```json
{
    "files.autoSave": "onFocusChange",
    "editor.renderWhitespace": "all",
    "terminal.integrated.shell.windows":"cmd.exe",
    "terminal.integrated.shellArgs.windows": ["/k","chcp","65001"],
    "code-runner.saveFileBeforeRun": true,
    "code-runner.runInTerminal": true,
    "C_Cpp.default.browse.path": ["${env:MINGW}/x86_64-w64-mingw32/include"],
    "terminal.integrated.rendererType": "dom"
}
```
主な設定は以下の通り

- editor.renderWhitespace スペースが見えるように
- terminal.integrated.shell.windows ターミナルを開いたときのシェル
- terminal.integrated.shellArgs.windows ターミナルをUTF-8にして日本語を表示できるように
- code-runner.saveFileBeforeRun コードを実行する前に保存
- code-runner.runInTerminal コードを実行する時にターミナルの中で実行
- C_Cpp.default.browse.path ヘッダファイルのパス

## テンプレートプロジェクトの作成
プロジェクト作成を簡単にするためにテンプレートプロジェクトを作成します．
Template Projects拡張機能のためのテンプレートプロジェクトを作成します．テンプレートプロジェクトは VSCode/data/user-data/User/ProjectTemplates以下にプロジェクト名のフォルダを作成してそこにテンプレートをおきます．
C Projectというテンプレートを作成するとフォルダ構成は次のようになります．

```
CPrograming/
         |- mingw64/
         |- VSCoduim/      
                 |- data/
                      |- user-data/
                             |- User/
                                   |- ProjectTemplates/
                                         |- C Project/
                                   ：
                                   └ settings.json 設定ファイル
                 ：
                 └ VSCodium.exe
         └ Start.cmd
```

このテンプレートの中身はVSCodiumのプロジェクト(フォルダ)そのものです．ここにコンパイル，デバッガ実行などの設定をしておきます．

ProjectTemplates以下は次のようにします．

```
ProjectTemplates/
  |- C Project/
    |- .vscode/
      |- launch.json
      └  tasks.json
    └ main.c
```

launch.jsonは以下の通り，

```launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "miDebuggerPath": "gdb.exe",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "build"
        }
    ]
}
```

注意は miDebuggerPathで指定しているgdb.exeをコマンド名だけにすること（起動スクリプトで実行パスの先頭に設定しているのでこれでポータブル環境のgdbが起動する），preLaunchTaskの設定が次のtasks.jsonのlabelと一致していること．
次にtasks.jsonの中身

```tasks.json
{
  "tasks": [
    {
      "type":"process",
      "label": "build",
      "command": "gcc.exe",
      "args": [
        "-g",
        "${file}",
        "-o",
        "${fileDirname}\\${fileBasenameNoExtension}.exe",
        "-lm",
        "-lws2_32"
      ],
      "problemMatcher": [
        "$gcc"
      ]
    }
  ],
  "version": "2.0.0"
}
```

ここもgcc.exeがコマンド名だけとなっていて実行パスから検索させること．また，typeがshellだとsettings.jsonのターミナルの設定が使われてうまくコマンドが起動しないので，processにすること．

他にもProjectTemplates以下にフォルダを追加して，プロジェクトの雛形を作っておけば複数のテンプレートを使い分けることもできます．上の例のプロジェクトは単一ソースファイルのプログラムを実行，コンパイル，デバッグするためのものなので，Makefileをおいて複数ファイルのプロジェクトの雛形を用意してもいいし，C++言語の雛形を用意しておいてもいいです．

授業では，後半でライブラリを使ってプログラムを書くためにライブラリやヘッダファイルを同梱した雛形を作りました．

## マルチフォルダワークスペースの作成
プログラミングの課題をやっていると，課題ごとにプロジェクト作成して，しかも過去の課題を参照したいと思うことが多いです．しかしVSCodeは１ワークスペース１フォルダが基本で，マルチフォルダワークスペースもありますが，使い方がわかりにくいです．そこで，最初からマルチフォルダワークスペースの設定をしておいて，そこにフォルダを追加していくことにします．

ついでにワークスペースもポータブル環境に含めればUSBに展開しておけばどこでも課題ができます．

CPrograming直下にworkspaceフォルダを作成して，そこにプロジェクトフォルダを作成しておきます．

```
CPrograming/
         |- mingw64/
         |- VSCoduim/      
                 |- data/
                      |- user-data/
                             |- User/
                                   |- ProjectTemplates/
                                         |- C Project/
                                   ：
                                   └ settings.json 設定ファイル
                 ：
                 └ VSCodium.exe
         |- workspace/
              |- project1/
                     |- .vscode/
                         |- launch.json
                         └  tasks.json
                     └ main.c
              └  ワークスペース.code-workspace
         └ Start.cmd
         
```

project1以下の内容はテンプレートプロジェクトと同じものとしておきます．ワークスペース.code-workspaceはワークスペースの設定ファイルで次のようにしておきました．

```json:ワークスペース.code-workspace
{
	"folders": [
		{
			"path": "project1"
		}
	],
	"settings": {}
}
```

## 配布ファイルの作成
配布ファイルの作成は単純にCProgramingをzipなどで圧縮して渡せば，ユーザは圧縮ファイルを好きな場所に展開するだけで使用することができます．

# カスタム環境の使い方
## インストール
カスタム環境を圧縮した配布ファイルをCPrograming.zipとします．インストールはこれを好きな場所に展開するだけです．ただし，展開するパス名に日本語フォルダ名が含まれているとデバッガが正しく動かないので注意が必要です．

また，ユーザが初心者の場合は配布入るを単にダブルクリックすると圧縮フォルダで中身が見えるのですが，この状態では使えないので，必ず「全て展開」で展開するように注意しておく必要があります．

## 起動
展開したフォルダの中にある Start.cmdをダブルクリックすれば起動します．初回起動時だけはなぜか日本語モードにならないので，そういう時は一度終了してもう一度起動し直します．

## ワークスペースを開く
まずはワークスペースを開く必要があります．メニューの「ファイル」から「ワークスペースを開く」という項目を選び，「ワークスペース.code-workspace」を選択します．

そうするとproject1というプロジェクトフォルダの中にmain.cや.vscodeフォルダがあるのが見えます．

## プログラムの編集
project1のmain.cを好きなように編集します．

## プログラムの簡易実行
Code Runnerの機能で，エディタの右上にある▷マークをクリックすると，編集中のプログラムをコンパイル＆実行できます．実行結果はエディタの下にターミナルが現れてここに表示されます．

## プログラムのデバッグ
左のアイコンから虫マークのアイコンをクリックするとデバッグモードになります．そこで上のデバッグのところのプロジェクトを編集中のプロジェクトに合わせて緑の▷をクリックすればデバッガが起動します．事前にブレイクポイントを指定しておかないとすぐにデバッガが終了するので注意が必要です．

## 新しいプロジェクトの作成
エディタの右の「ワークスペース」のところで右クリックすると「ワークスペースにフォルダを追加」というメニューがあるので，それを選択します．
出てきた選択ウィンドウで右クリックして「新規作成」「フォルダ」を選んで新しいプロジェクトをフォルダを作成し，そのフォルダを選択して「追加」ボタンをクリックします．

「ワークスペース」のところに今作成したフォルダが表示されているので，そのフォルダを右クリックすると「Create Project from Template」という項目があるので，それを選択します．すると上部でテンプレートを選択するメニューが表示されているので，好きなテンプレートを選択すると，テンプレートが適用されて設定やサンプルのmain.cが作成されます．

# 最後に
とりあえず今年度の授業でこのカスタムポータブル環境を使い始めています．何度言っても日本語フォルダ名（だいたい授業名のフォルダ）に展開してしまう学生がいてデバッガが起動しないと言ってきたり，zipの展開方法がわからなくてつまずいたり（推奨パソコンにWinZip試用版が入っていて右クリックメニューに全て展開がない，しかも期限が切れてて警告がでるのも悪い），がっかりするようなトラブルが出たりしますが，なんとか使えているようです．