gccgoにclangのインクルードパスを引っ掻き回されたという話

といっても別にgccgoが悪い訳ではなさそう。

# tl;dr
Ubuntu18.04でのことですが、gccgoをaptを使ってインストールしたところEmacsの`irony-mode`の補完が機能しなくなり、flycheckの`c/c++-clang`が「標準ヘッダが見つからない」とエラーを吐くようになりました。書いていたのはC++のコードです。

理由としては
1. gccgoが依存するgccgo-8、それが依存するgcc-8その他が、元々入っていたgcc(バージョン7)に加えてインストールされる
2. clangのインクルードパスに**存在しない**gcc-8のものが候補として加わる。
3. clangがバージョン7向けのパスを見に行かなくなるので、`irony-mode`やflycheckがうまく機能しなくなる。
ということのようです。

# 検証
## gccgoの依存関係
gccgo-8は次のようにgcc-8に依存します。

```plaintext
% apt-cache depends gccgo-8
gccgo-8
  依存: gcc-8-base
  依存: gcc-8
  依存: libgo13
  依存: libc6-dev
  依存: libc6
  依存: libgmp10
  依存: libisl19
  依存: libmpc3
  依存: libmpfr6
  依存: zlib1g
  競合: golang-go
  破壊: <libgo12>
  提案: gccgo-8-doc
  提案: libgo13-dbg
  置換: <libgo12>
```
## clangのインクルードパス
### gccgoを入れた直後

```plaintext

% clang++ -v example.cpp                      
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7.3.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.3.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8.0.1
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1

<略>

ignoring nonexistent directory "/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/backward"
ignoring nonexistent directory "/include"
ignoring duplicate directory "/usr/include/clang/6.0.0/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++
 /usr/include/clang/6.0.0/include
 /usr/local/include
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
fib.cpp:1:10: fatal error: 'cstdio' file not found
#include <cstdio>
         ^~~~~~~~
1 error generated.

```
GCCの各バージョンが候補としてあげられていますが、最終的に8.0.1が選択されています。が、ヘッダを見けられず、コンパイルは中断してしまいます。~~7の方も見に行ってくれやい。~~

「ヘッダが見つからないならインストールすればいいじゃない」ということでg++-8を入れると無事コンパイルできるようになります。

### gccgoを消した後
このままg++-8を入れるかインクルードパスを明示的に指定しても良いかもしれませんが、以下ではgccgoや依存パッケージ類を削除して、インクルードパスがどうなるか確認してみましょう。

まずは削除

```plaintext
% sudo apt remove gccgo gcc-8
% sudo apt autoremove
```
そしてコンパイル

```plaintext
% clang++ -v example.cpp        
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7.3.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.3.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8.0.1
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7.3.0

<略>

ignoring nonexistent directory "/include"
ignoring duplicate directory "/usr/bin/../lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0"
ignoring duplicate directory "/usr/include/clang/6.0.0/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/bin/../lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0
 /usr/bin/../lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0
 /usr/bin/../lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward
 /usr/include/clang/6.0.0/include
 /usr/local/include
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
<略>
```
今度はGCC7.3.0が選ばれました。パスもちゃんと存在しているようです。コンパイルもつつがなく終了し、`irony-mode`、flycheckも無事機能するようになりました。

# まとめ
clangやclangを使うツールがおかしくなったときは、今回と同じような原因を疑ってみるといいかもしれません。