GCC本体を快適に開発する

はじめに

言語問わず、LLVMと比べGCCの貢献に関するドキュメントが少なく感じるので、メモ程度に残しておきます。GCCのビルドの方法は色んなところに書いてあるので、そちらを参照してください。

対象読者は以下のとおりです。

ビルド

./gcc/configureでビルドコンフィギュレーションを実行します。典型的なオプションは以下の通り。

  • --disable-bootstrap : コンパイラのブートストラップを無効化
  • --disable-multilib : 異なるABIなどをサポートするためのライブラリをビルドしないようにする
  • --enable-languages=rust : ビルドする言語を選択する。この場合はRustを有効化
  • --enable-checking=extra,gimple,tree,types : コード生成時のツリーのチェックを有効化

詳しくはGCCのHPを参照: https://gcc.gnu.org/install/configure.html

makeを実行する時は-j($nproc)を渡しましょう。

テスト

End-to-endテストはgcc/gcc/testsuite/{language}/以下にあります。 単体テスト(gccではselftestsと呼ばれる)はgcc/gcc/{language}内にあります。

End-to-endテストではdejagnuというフレームワークが使われています。 言語処理系で典型的な、期待されるエラーやその内容、標準出力やプロセスの終了値をチェックできます。

以下はCプリプロセッサのテスト例(dejagnu)です。

/* PR preprocess/95183  */

/* { dg-do preprocess } */

#define f(x) x

f( /* { dg-error "-:unterminated" "unterminated macro" } */

LSP

GCCC++で書かれています。 ある程度大きなソースコードなので、LSPはClangdをつかうと速くて快適です。

Clangdはビルド時のコンパイラオプションを収集したcompile_commands.jsonというファイルを認識してLSPとして動作します。 GCCはビルドシステムとしてMakefileを使います。CMakeと異なり、Makefileはcompile_commands.jsonを生成してくれません。そこで、Bearというツール経由でmakeコマンドを呼び出すことでcompile_commands.jsonを生成することができます。

$ ls
gcc
$ mkdir gcc-build && cd gcc-build
# ビルドのコンフィギュレーション
$ ../gcc/configure ...
...
# bear経由でビルドする
$ bear -- make -j($nproc) ...
...
# 生成されたcompile_commands.jsonをコピー
$ cp compile_commands.json ../gcc/compile_commands.json

注意: 自分の環境ではmakeに-j($nproc)を渡すとbearがcompile_commands.jsonを生成してくれませんでした。原因はよくわかりません。

Clangdでシステムヘッダが見つからない場合

clangdはヒューリスティック<string.h>などのヘッダーファイルを探すため、見つからないことがたまにあります。その場合は、.clangdという名前のファイルを作り、以下のように適当にインクルードパスを指定すればよいです。

# .clangd
CompileFlags:
  Add: [
    "-I/usr/lib/gcc/x86_64-linux-gnu/11/include",
    "-I/usr/include/x86_64-linux-gnu",
    "-I/usr/include",
    "-I/usr/include/c++/11",
    "-I/usr/include/x86_64-linux-gnu/c++/11",
    "-I/usr/include/c++/11/backward"
  ]

参考: https://stackoverflow.com/questions/17939930/finding-out-what-the-gcc-include-path-is

コミットログ

GCCのコミットメッセージは定められたフォーマットに従う必要があります。 以下は実際のコミットメッセージです。(名前とメールは伏せました。)

gccrs: Refactor FnType deprecated API

gcc/rust/ChangeLog:

    * backend/rust-compile-expr.cc (CompileExpr::visit): Use new API.
    * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): Use new API.
    * typecheck/rust-tyty-cmp.h: Remove old API.
    * typecheck/rust-tyty.cc (FnPtr::is_equal): Use new API.
    * typecheck/rust-tyty.h: Remove old API.
    * typecheck/rust-unify.cc (UnifyRules::expect_fnptr): Use new API.

Signed-off-by: Name <Email>

このようなChangeLogを自動的に生成するにはgit gcc-commit-mklogコマンドを使います。 gccディレクトリで./contrib/gcc-git-customization.shを実行することでインストールできます。

おわりに

役に立てば幸いです!