Visual Studio Codeから本家Visual Studioのプロジェクトをコンパイル

## はじめに

何番煎じな内容です。先人に感謝。あくまで自分用まとめの公開。Visual StudioからVisual Studio Code(VSCode)へ移行したくなってきた人向け。

## MSBuildを使えるように


1. MSBuildをインスコする。Visual Studio Communityのインスコでも可。
1. 環境変数でmsbuildのpathを通す。VSCodeの再起動も必要。
1. コマンドプロンプトからmsbuildコマンドが通るか確認。

**追記：msbuildが安定に動作するのはシェルがcmd.exeの場合。よって、デフォルトのターミナルがGit bashやWSLの場合にもtaskとしてはcmd.exe上で実行できるようにしました。**

## VSCodeのビルドタスクとして追加

VSCodeのビルドタスク（`Ctrl+Shift+B`でショートカット実行可能）として登録すべく、tack.jsonを作成する。

おもむろにVSCode上でCtrl+Shift+Bを押す。（この時、`*.vcxproj`ファイルと同ディレクトリ階層のファイルを開いている必要があるかもしれない）。すると、task.jsonがないので作れと言われるので、そのリンクを押すと、MSBuild用のテンプレのtask.jsonが作られる。

プロジェクトファイルの拡張子はC++,C#などによって異なるので適当に読み替えること。

### task.json中身の書き換え

実際に作ったものは以下。Debug, Release用にそれぞれビルドとクリーンで、計四種類のタスクを登録した。


```json
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [        
        {
            "label": "Build-Debug",
            "type": "shell",
            "command": "msbuild",
            "args": [
                "FlyAM.vcxproj",
                "/property:Configuration=MPI-Debug;Platform=x64",
                "/t:build",
                "/consoleloggerparameters:NoSummary"
            ],
            "group": "build",
            "presentation": {
                "reveal": "always",
                "echo": true,
                "focus": false,
                "panel": "shared"
            },
            "problemMatcher": "$msCompile",
            "options": {
                "shell": {
                    //to execute task on the "cmd.exe" independent of default shell.
                    "executable": "cmd.exe",
                    "args": ["/d", "/c"]
                }
            }
        },
        {
            "label": "Build-Release",
            "type": "shell",
            "command": "msbuild",
            "args": [
                "FlyAM.vcxproj",
                "/property:Configuration=MPI-Release;Platform=x64",
                "/t:build",
                "/consoleloggerparameters:NoSummary"
            ],
            "group": "build",
            "presentation": {
                "reveal": "always",
                "echo": true,
                "focus": false,
                "panel": "shared"
            },
            "problemMatcher": "$msCompile",
            "options": {
                "shell": {
                    //to execute task on the "cmd.exe" independent of default shell.
                    "executable": "cmd.exe",
                    "args": ["/d", "/c"]
                }
            }
        },
        {
            "label": "Clean-Debug",
            "type": "shell",
            "command": "msbuild",
            "args": [
                "FlyAM.vcxproj",
                "/property:Configuration=MPI-Debug;Platform=x64",      
                "/t:clean",
                "/consoleloggerparameters:NoSummary"
            ],
            "group": "build",
            "presentation": {
                "reveal": "always",
                "echo": true,
                "focus": false,
                "panel": "shared"
            },
            "problemMatcher": "$msCompile",
            "options": {
                "shell": {
                    //to execute task on the "cmd.exe" independent of default shell.
                    "executable": "cmd.exe",
                    "args": ["/d", "/c"]
                }
            }
        },
        {
            "label": "Clean-Release",
            "type": "shell",
            "command": "msbuild",
            "args": [
                "FlyAM.vcxproj",
                "/property:Configuration=MPI-Debug;Platform=x64",      
                "/t:clean",
                "/consoleloggerparameters:NoSummary"
            ],
            "group": "build",
            "presentation": {
                "reveal": "always",
                "echo": true,
                "focus": false,
                "panel": "shared"
            },
            "problemMatcher": "$msCompile",
            "options": {
                "shell": {
                    //to execute task on the "cmd.exe" independent of default shell.
                    "executable": "cmd.exe",
                    "args": ["/d", "/c"]
                }
            }
        }
    ]
}
```

- "taskName"：適当な命名を。debug,releaseの区別やMPIの有無などがわかり易く名前付けする
- "type"：shellかprocessを選べるが、挙動の違いが微妙でよくわからん。とりあえずshellでもよさそう。
- "command"：MSbuildのフルパスを指定しても良いが、上記の設定でpathが通っていれば"msbuild"と書くだけでもOK。
- "args"にはmsbuildコマンドへ対する引数を指定する。引数は用意すると良いものは以下
  - 第一引数：目的のvcxprojファイルパスかslnファイルパス。slnを指定した場合は全ての構成に対してビルドに行く。
  - 第二引数：`"/p:Configuration=Release;Platform=x64"`の形式で、Visual Studioでいう"ソリューション構成"とプラットフォームを書く。ReleaseやDebugがデフォルトだが、各自でカスタムしている場合もあるだろう。名前を知りたいときは、VSCodeでvcxprojファイルを開いて`<Congdiguration>`タグを探すべし。Configurationを何も指定しないとデフォルトで"Debug"がターゲットになる。そもそも"Debug"という構成名を使っていないプロジェクトの場合もあるだろうから指定するのが望ましい。その他のオプションは[https://docs.microsoft.com/ja-jp/visualstudio/msbuild/common-msbuild-project-properties?view=vs-2019](https://docs.microsoft.com/ja-jp/visualstudio/msbuild/common-msbuild-project-properties?view=vs-2019)を参照されたし。
  - 第三引数：`"/t:build"`とすればビルドを行う。`"/t:clean"`とすればクリーンを行う。`"/t:rebuild"`とすればリビルドを行う模様。
  - 第四引数：`"/consoleloggerparameters:NoSummary"`コンパイル後に警告をまとめて再表示するかどうか。お好みで。

### 経験則


- 第一引数にvcxprojを指定して上手く行かない時は、slnを指定してみよう。上手く行くことがある。
- 経験則として、`"/p:Configuration"`だけを指定しているとvcxprojのビルドでは上手く行かないことがあったが、`"/p:Platform"`も指定すれば上手く行くようになった。

## ビルドするには

`Ctrl+Shift+B`を押して、目的の項目を選べばビルドorクリーンされる。

<del>ターミナルの種類はcmdの他にGit bashでも行けた。Git bash大好き</del>。
**追記：** `options`項目を書くことで、デフォルトシェルや開いているターミナルのシェルに依存せずにcmd上で安定にビルドできる。

## 最後に

MSBuildのおかげでvc.exeを直接呼ばずに済むのはありがたい。コンパイル時の各種設定を変えたいときは、本家Visual Studioから行えば良いし。

VSCodeに移行したい理由は、起動速度と、ぶっちゃけGit Graphのみ。

### 参考サイト：

[https://code.visualstudio.com/docs/editor/tasks](https://code.visualstudio.com/docs/editor/tasks)

[https://www.off-soft.net/ja/software/develop2/vscode-cpp-develop-msbuild.html](https://www.off-soft.net/ja/software/develop2/vscode-cpp-develop-msbuild.html)

[https://qiita.com/hibara/items/fa66c3241293b7d43eae](https://qiita.com/hibara/items/fa66c3241293b7d43eae)