鬱猫のつぶやき

鬱猫が日々思っていることをつづります

bear を使った compile_commands.json 生成

はじめに

clangd を使う際、JSON Compilation Database (compile_commands.json) が必要になります。CMake を使ってビルドするプロジェクトの場合は、CMAKE_EXPORT_COMPILE_COMMANDS=1 を指定すれば簡単に export できますが、そうでない場合は別のツールを使って生成する必要があります。

今回は、汎用的に compile_commands.json を生成するツール Bear の Mac への導入方法について紹介します。

Homebrew があれば以下のコマンドで入ります。

$ brew install bear

ただ、このままだと Bear が動いてくれません。この後、以下の二つの手順を踏む必要があります。

  • System Integirty Protection の無効化
  • 標準ライブラリのヘッダファイルの再インストール

System Integrity Protection の無効化

Bear のリポジトリにも注意点として挙げられていますが、library preload を無効化しているシステムでは Bear は使えません。Macだと (私は Majave を使っていますが、それ以降でもおそらく) デフォルトで library preload ができないようになっているため、Bear が出力する compile_commands.json が空ファイルになります。

この library preload を許可するためには、System Integrity Protection を無効化してやる必要があります。デフォルトではこれは有効になっています。

$ csrutil status | grep 'System Integrity Protection'
System Integrity Protection status: enabled.

System Integrity Protection の無効化ですが、以下の手順で行えます。

  1. OS の再起動
  2. Cmd-R を押しっぱなしにして、リカバリーモードに入る
  3. ユーティリティをクリック
  4. Terminal をし、Terminal を起動
  5. csrutil disable を打ち込む
  6. OS の再起動

再起動した後、再度 Terminal を開き、System Integrity Protection が無効になっていることを確認します。

$ csrutil status | grep 'System Integrity Protection'
System Integrity Protection status: disabled.

標準ライブラリのヘッダファイルの再インストール

次は標準ライブラリのヘッダファイルの再インストールです。これをやらないとこのイシューで挙げられている問題点に遭遇し、標準ライブラリのヘッダーが見つからずコンパイルできなくなります。

解決策としてはイシューのスレッドのこれにしたがって、ヘッダーの再インストールを行います。

JSON Compilation Database を生成してみる

これで compile_commands.json が生成できるようになりました。適当な C 言語のプロジェクトで compile_commands.json を早速作成してみましょう。

今回は高機能逆アセンブラである radare2 の compile_commands.json を生成してみます。

$ git clone https://github.com/radareorg/radare2.git
$ cd radare2
$ ./configure
$ bear make all
$ ls compile_commands.json
compile_commands.json

以下のような compile_commands.json ができていることが確認できます。

[
    {
        "arguments": [
            "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang",
            "-c",
            "-fno-common",
            "-fPIC",
            "-g",
            "-Wall",
            "-D__UNIX__=1",
            "-DR2_PLUGIN_INCORE",
            "-I/Users/utsuneko/Documents/radare2/libr/..//shlr",
            "-I/Users/utsuneko/Documents/radare2/libr/../shlr/zip/include",
            "-I/Users/utsuneko/Documents/radare2/libr",
            "-I/Users/utsuneko/Documents/radare2/libr/include",
            "-fvisibility=hidden",
            "-I../../shlr/sdb/src//src",
            "-DHAVE_FORK=1",
            "-o",
            "chmod.o",
            "chmod.c"
        ],
        "directory": "/Users/utsuneko/Documents/radare2/libr/util",
        "file": "chmod.c"
    },
...

まとめ

Bear の Mac への導入方法についてまとめました。

compile_commands.json があると、VSCode の補完がいい感じで効くようになったりします。他にも最近リリースされた Sourcetrail を C 言語のプロジェクトで使う場合も compile_commands.json が必要になります。   この compile_commands.json の作成、地味に苦労したので、誰かの役に立てればと思い、ブログに記事としてまとめました。