llvm-clang環境のDockerを作ってDocker Hubにpushした。

#TL;DR

```bash:bash
$ docker run -v"$PWD":/myapp -w /myapp naktak/clang
```
でbashが走るので

```bash:naktak/clang
$ clang -v
clang version 5.0.0 (trunk 294803)
```
でclangやclang++が使えます。


#きっかけ
某所で見た問題の解答をプログラムした結果をgccとclangでコンパイルして比較したくなったのだが、gccは[公式Docker](https://hub.docker.com/_/gcc/)があるのにllvm-clangは公式Dockerが見つからなかったので、どうせならソースから自作してみようかと。

##問題
//┏┳┳┳┳┓ 
//┣╋╋╋╋┫ 
//┣╋╋╋╋┫ 
//┣╋╋╋╋┫ 
//┣╋╋╋╋┫ 
//┗┻┻┻┻┛ 
//上記の6X6の通路を左上から右下へ到達する時に 
//同じ道を通らずにたどり着くルートは何通りあるか？ 
//ただし、同じ交差点は何度通ってもいい

##回答
解答は[これ](https://github.com/nak1114/docker-template/blob/master/clang/hogeb1.c)で、深さ優先探索と軽い枝切りで実装してます。


#llvm-clang環境の作成
環境構築の手順は以下の通りです。
- Dockerfileを作成して
- Docker imageを構築して
- DockerHubにpushする

##Dockerfile作成
###llvm-clangのビルド＆インストール方法
[Ubuntu 16.04: リポジトリのLLVM/Clangをビルドしてインストールする](https://www.hiroom2.com/2016/05/08/ubuntu-16-04%E3%81%AB%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%AEllvm-clang%E3%82%92%E3%83%93%E3%83%AB%E3%83%89%E3%81%97%E3%81%A6%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B/)
をほぼ踏襲しました。

###Dockerfile作成方法
[効率的に安全な Dockerfile を作るには](http://qiita.com/pottava/items/452bf80e334bc1fee69a)が大変参考になりました。

###作成したDockerfile

```Dockerfile:Dockerfile
FROM ubuntu

RUN set -x && \
    apt-get update && \
    apt-get install -y make cmake gcc g++ python libtool zlib1g zlib1g-dev subversion && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    cd / && \
    mkdir llvm && \
    cd /llvm && \
    svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm && \
    cd /llvm/llvm/tools && \
    svn co http://llvm.org/svn/llvm-project/cfe/trunk clang && \
    cd /llvm/llvm/tools/clang/tools && \
    svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk extra && \
    cd /llvm/llvm/projects && \
    svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt && \
    cd /llvm && \
    mkdir build && \
    cd build && \
    cmake -G "Unix Makefiles" ../llvm/ -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release && \
    make -j$(grep processor /proc/cpuinfo | wc -l) REQUIRES_RTTI=1 && \
    make install && \
    cd / && \
    rm -rf llvm

ENTRYPOINT ["/bin/bash"]
```
ファイル自体は[ここ](https://github.com/nak1114/docker-template/blob/master/clang/Dockerfile)に置いておきます。
必要パッケージがネタ元と違う以外は全く一緒です。

##Docker image構築
DockerfileのあるDirに降りてbuildするだけです。

```bash:docker-template/clang
$ docker build -t naktak/clang .
```

参考サイトではRAMが2GB必要と書いてありましたが、2GBだと97%まで来て最後のlinkerで落ちました。最高に切ない。
メモリ割り当てを3GBまで増やしたら通ったので、もし自分でbuildするときは余裕をみて4GBくらい用意しましょう。

私のハードウェアは以下の通りです。

```bash:/proc/cpuinfo
model name      : Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz
cpu cores       : 2
processor       : 1
```
```bash:/proc/meminfo
MemTotal:        3057012 kB
```
これでbuild時間は30分くらいでした。


##Docker push

###Docker Hub アカウント作成
まずはDockerHub上にアカウントを作ります。下の必要事項を書いてSignUpします。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/109103/2ece5131-2972-57eb-f25b-937af8e1a620.png)

するとメールに確認アドレスが届くのでclickすれば登録完了です。

###DockerHubにログイン
loginコマンドでDockerHubにログインします。

```bash:bash
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: naktak
Password:
Login Succeeded
```

###Dockerイメージをpush
一番上の`8c6c5a1d33e4`が今回作成した層です。その下はubuntuのものなのでpushされませんでした。

```bash:bash
$ docker push naktak/clang
The push refers to a repository [docker.io/naktak/clang]
8c6c5a1d33e4: Pushed
5eb5bd4c5014: Mounted from library/ubuntu
d195a7a18c70: Mounted from library/ubuntu
af605e724c5a: Mounted from library/ubuntu
59f161c3069d: Mounted from library/ubuntu
4f03495a4d7d: Mounted from library/ubuntu
latest: digest: sha256:ce63be3a47a9ad6a3b683cf883be2655340d5905654189db13c95c792814a567 size: 1570
```

###Dockerイメージを確認

https://hub.docker.com/ にアクセスして`sign in`してからDashboardやMy Profileからpushしたimageが存在するかを確認できます。
![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/109103/6790b086-5e54-91e1-6a67-72d042befd82.png)

###Dockerイメージを使用

```bash:bash
$ docker run -v"$PWD":/myapp -w /myapp naktak/clang
```
で`/bin/bash`が動きますので、中でclangを使用できます。

```bash:naktak/clang
$ clang -v
clang version 5.0.0 (trunk 294803)
```

#最後に
軽い気持ちで始めて、特に問題もなく環境構築出来てしまった。
dockerは非常に簡単でした。
ちなみに冒頭の問題の答えは以下の通りで1086297184回、約33秒でGCCとほとんど同じでした。

```bash:naktak/clang
$ clang -Ofast -o myapp hogeb1.c
$ ./myapp
start 3f00000003f:820820820
total=1086297184: time=33.632360[sec]
```