といっても別にgccgoが悪い訳ではなさそう。
tl;dr
Ubuntu18.04でのことですが、gccgoをaptを使ってインストールしたところEmacsのirony-mode
の補完が機能しなくなり、flycheckのc/c++-clang
が「標準ヘッダが見つからない」とエラーを吐くようになりました。書いていたのはC++のコードです。
理由としては
- gccgoが依存するgccgo-8、それが依存するgcc-8その他が、元々入っていたgcc(バージョン7)に加えてインストールされる
- clangのインクルードパスに存在しないgcc-8のものが候補として加わる。
- clangがバージョン7向けのパスを見に行かなくなるので、
irony-mode
やflycheckがうまく機能しなくなる。
ということのようです。
検証
gccgoの依存関係
gccgo-8は次のようにgcc-8に依存します。
% 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を入れた直後
% 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や依存パッケージ類を削除して、インクルードパスがどうなるか確認してみましょう。
まずは削除
% sudo apt remove gccgo gcc-8
% sudo apt autoremove
そしてコンパイル
% 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を使うツールがおかしくなったときは、今回と同じような原因を疑ってみるといいかもしれません。