指先一つで立ち上げるD言語開発環境

# D言語の開発環境、皆さんどうやって作ってますか？

先日、Twitter にD言語の開発環境に関するこんなツイートが流れていました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ていうかD言語の開発環境って、テキトーにdmdのzipダウンロードしてきて、解凍して、パス通すだけじゃないのか…？あと適当にだいたいいつも使ってるテキストエディタでぺちぺち書いていけばいいんじゃないのか…？</p>&mdash; SHOO (@mono_shoo) <a href="https://twitter.com/mono_shoo/status/1198999863582580736?ref_src=twsrc%5Etfw">November 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

確かに公式サイトの [dlang.org](https://dlang.org) からは、dmd などのコンパイラの他にパッケージマネージャ兼ビルドマネージャである `dub` もダウンロードできるため(というかコンパイラとセットでダウンロードできる)、最低限の環境構築であればこれにエディタがあれば問題ありません。

でもせっかくだったら、IDE でリッチな機能(インテリセンス、オンザフライなエラーチェックなど)を使って開発してみたいですよね。

今回は ldc などのコンパイラや、VSCcode の拡張機能である Code-d をインストールして開発環境を整える…**という話はしません！**

開発用のツールを手でインストールするのは20世紀までの話です。環境構築はもっと楽ちんになるべき。

# 前提条件
残念ながら、いくつかのソフトウェアはまだ自分でインストールする必要があります。敗北感に苛まれながら以下を各自でインストールしてください。

- [Visual Studio Code](https://code.visualstudio.com)
- [Remote - Container extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) (VSCode の拡張)
- git
- Docker (Docker for mac、Docker for Windows でもいけるはず)

また、以降で説明する手順は Github アカウントを持っていることを前提としていますが、アカウントがなくても特に問題ありません。

# で、どうやるの？
VSCode の remote container 拡張を使うと、リポジトリを指定したコンテナ内に展開(厳密には volume mount)し、コンテナ内にインストールされたツールを使って開発することができます。D言語用に必要な設定を置いた[テンプレートリポジトリ](https://github.com/tom-tan/dlang-for-remote-container-template)を用意したので、今回はそれを使って開発環境の設定も含んだ新規リポジトリを作成します。

以下が具体的な手順です。

- 以下の URL にアクセスします
  - https://github.com/tom-tan/dlang-for-remote-container-template
- ページ内の `Use this template` をクリックして新規リポジトリを作成する
  - Github アカウントを持っていない方は、単純にこの工程をスキップしてください
- ローカルにリポジトリを clone する
  - Github アカウントを持っていない方は、上記の リポジトリを clone してください
- VSCode から `Remote-Containers: Open Folder in Container...` (画面左下の `><` みたいなボタンから選択できる) を使い、clone したリポジトリを開く
- できあがり！
  - ~~指先一つじゃなかった~~
  - 最初にD言語のソースを開いた時に、serve-d や dcd などの IDE 関係のソフトウェアがコンテナに自動的にインストールされます
  - 新規ターミナルからコンテナ内の各種ツールを使えます。デフォルトでは [`dlang2/ldc-ubuntu`](https://hub.docker.com/r/dlang2/ldc-ubuntu) を使っているため、dub や ldc が開発ツールとして使えます。

# FAQ
- あのパッケージがほしい
  - `.devcontainer/devcontainer.json` の `postCreateCommand` フィールドに、コンテナ作成 or pull 後に実行するコマンドを指定できます。

    ```json:.devcontainer/devcontainer.json
    {
      ...
      "postCreateCommand": "apt-get update && apt-get install -y hogefuga",
      ...
    }
    ```
- ldc じゃなくて dmd を使いたい
  - `.devcontainer/devcontainer.json` の `image` フィールドで使用するコンテナイメージを指定できます。
    - https://hub.docker.com/u/dlang2 で各種コンパイラ向けのイメージが提供されています。

    ```json:.devcontainer/devcontainer.json
    {
      ...
      "image": "dlang2/dmd-ubuntu:2.087.1", // dmd が入ったイメージを使う場合
      ...
    }
    ```
- 静的リンクされたバイナリを作りたい！
  - テンプレート内に、ldc-ubuntu をベースに musl 向けクロスコンパイル環境を用意する Dockerfile (`cross.Dockerfile`)を用意しています。`.devcontainer/devcontainer.json` の `image` フィールドの代わりに `dockerFile` フィールドを使うことで、指定した `Dockerfile` からビルドしたイメージで開発できるようになります。

    ```json:.devcontainer/devcontainer.json
    {
      ...
      // "image": "dlang2/ldc-ubuntu:1.18.0", // この行は削除
      "dockerFile": "cross.Dockerfile",
      ...
    }
    ```
  - Alpine Linux ベースのコンテナを使う方法もありますが、前述した IDE の機能を提供するツールが動かないためお勧めしません。
- クロスコンパイル環境を使いたい
  - `apt` で欲しい環境用のC言語のクロスコンパイラをインストール後、`ldc-build-runtime` で各環境向けの標準ライブラリを作成できます。上の `cross.Dockerfile` にも実例がありますので参考にしてください。
      - 参考: https://wiki.dlang.org/Building_LDC_runtime_libraries

- Windows のバイナリが吐けないよ！
  - [公式のドキュメント](https://code.visualstudio.com/docs/remote/containers)にあるように、Windows コンテナはサポートされていません。現状では Windows 用のクロスコンパイル環境を作るしかなさそうです。
  - そのうち Windows コンテナもサポートされるといいなぁ。

# TODO
PR お待ちしてます！

- デバッガ
  - ~~使ったことないからわからん~~
  - 対応しました！ ブレークポイントなどの機能が利用可能です。
- Github Action 用の CI 用テンプレート
- その他もっと便利になる設定各種

# 最後に
リポジトリにソースコードや CI 設定だけでなく、開発環境も含め配布する時代がやってきました！
VSCode で開発をしている方は、ぜひ活用しましょう！