auto-complete-clang-asyncのclang-completeをwindows上でgccを使ってビルドした

windows上でemacsのpackageのauto-complete-clang-asyncのserverとなるclang-completeをビルドしようとすると、デフォルトではVisual Studioでコンパイル・リンクするようになっているので、gccでやるためにいろいろ試行錯誤した。

# 環境
* Windows 10
* MinGW
    * gcc 5.3.0
    * make 3.81
* LLVM
    * clang 3.8.0
* emacs 26.1 [^1]
[^1]: 今回は直接的には出てきませんが、私はshell-mode内で行いました。clang-completeは普通emacs上でしか利用しないので、この後の説明にあるpathは、emacs内のみで通すので問題ありません

# PATHを通す
以下のものにPATHを通しておくと、フルパスを打たなくていいので楽です。これからの説明では、ここにPATHが通っているものとして行います。

* [LLVM](https://llvm.org/)
    * llvm-config (*LLVM/bin/* [^2])
    * libclang.dll (上に同じ)
* [MinGW](http://www.mingw.org/)
    * gcc (*MinGW/bin/* [^2])
    * make (*MinGW/msys/1.0/bin/* [^2])

[^2]: 普通にインストールしたら**多分***Program Files*の下にあるとおもうので、下記のディレクトリには*"C:/Program Files/"* が頭に付いていると思ってください。私は*.emacs.d*内に落としていて実情が分からないのでこういう書きかたになっています

# ダウンロード
clang-completeのソースは[ここ](https://github.com/Golevka/emacs-clang-complete-async)からダウンロードしてね
auto-complete-clang-async.elの方はmelpaからもダウンロードできるよ！

# インストール

## まずはお決まりの

* コマンドプロンプト(もしくはemacsのshell)を起動
* カレントディレクトリをダウンロードしたフォルダにする

## 利用する引数の取得
下記のコマンドを入力・実行

```shell
llvm-config --cflags
```
すると、次のようなものが得られる[^3]。

[^3]: makefileを見るか`make install`を実行してみれば分かるが、ここで得られるものは、makeするときに内部でgccに引数として渡される。

```shell
-Ic:/<自身がLLVMをインストールしたpath>/LLVM/include  
/DWIN32 /D_WINDOWS /W3   /MP -D_CRT_SECURE_NO_DEPRECATE 
-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE 
-D_CRT_NONSTDC_NO_WARNINGS -D_SCL_SECURE_NO_DEPRECATE 
-D_SCL_SECURE_NO_WARNINGS -wd4146 -wd4180 -wd4244 -wd4267 
-wd4345 -wd4351 -wd4355 -wd4503 -wd4624 -wd4800 -wd4291 
-w14062 -we4238 -D__STDC_CONSTANT_MACROS 
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
```

2行目を見ると、`/DWIN32 /D_WINDOWS /W3 /MP ` という部分がある。また、5行目には、`-wd4146 -wd4180 -wd4244 -wd4267 -wd4345 -wd4351 -wd4355 -wd4503 -wd4624 -wd4800 -wd4291 -w14062 -we4238` という部分がある。この2箇所は、恐らくgccでのコンパイルを想定していない引数であり[^4]、makeの実行時にgccがエラーを吐くため、削除する。すると、

```shell
-Ic:/<自身がLLVMをインストールしたpath>/LLVM/include 
 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS 
-D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS 
-D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS 
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS 
-D__STDC_LIMIT_MACROS
```
のようなものが残る。これをあとで使う。

## makeでコンパイルしよう！
下記のコマンドを入力・実行(見やすいように改行をいれているのでそのままコピペして実行するとたぶんミスります。改行をとってから実行してください)

```shell
make install CC=gcc 
CFLAGS="-std=c99 -Ic:/<自身がLLVMをインストールしたpath>/LLVM/include 
-D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS 
-D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS 
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS 
-D__STDC_LIMIT_MACROS 
-D LINE_MAX=2048" 
```
まずはじめの`CC=gcc`でCコンパイラの指定を行う。次にCFLAGSでgccに渡す引数を指定する。`-std=c99`は、clang-completeを普通にmakeすると勝手につくので付けておいた。
そのあとの3-7行目は先程llvm-configから取得したものを貼り付けたもの。
最後の行の`-D LINE_MAX=2048`は、なぜか私の環境ではlimits.hでLINE_MAXが定義されてなかったので、定義しておいた。

これを実行すると、コンパイルまではうまくいき、リンクのときに失敗する。

## リンクしよう！
makeがerrorで止まる直前に実行されたコマンドをコピーすると、

```shell
gcc -std=c99 
-Ic:/<自身がLLVMをインストールしたpath>/LLVM/include 
-D_CRT_SECURE_NO_DEPRECATE-D_CRT_SECURE_NO_WARNINGS 
-D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS 
-D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS 
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS 
-D__STDC_LIMIT_MACROS -D LINE_MAX=2048    
src/obj/completion_serv.o src/obj/main.o 
src/obj/msg_dispatcher.o src/obj/msg_handlers.o 
src/obj/parse_results.o 
-Lc:/<自身がLLVMをインストールしたpath>/LLVM/lib -lclang 
-o clang-complete

c:/<自身がMinGWをインストールしたpath>/mingw/mingw32/bin/ld.exe: cannot find -lclang
```
となっている。エラーの内容は、`-lclang`がない、というものだ。libclang.dllはdllだから-lで接頭のlibを省略不可なのだろうか。よくわからないが、`-llibclng`にすることでエラーはなくなるので、そのように変更して、最後のコマンドだけ再実行する。つまり、

```shell
gcc -std=c99 -Ic:/<自身がLLVMをインストールしたpath>/LLVM/include -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D LINE_MAX=2048    src/obj/completion_serv.o src/obj/main.o src/obj/msg_dispatcher.o src/obj/msg_handlers.o src/obj/parse_results.o -Lc:/<自身がLLVMをインストールしたpath>/LLVM/lib -llibclang -o clang-complete
```
を実行する。うまくいけばこれでclang-completeが生成される。

# 最後に
どこかミスってたらすみません。備忘録的な感じで書いたのでみんなの参考になるかは分かりませんが、お役に立てたら嬉しいです。

[^4]: おそらくVisual Studioによるコンパイルを想定している