#author("2023-04-08T12:11:59+09:00","","") #topicpath /////////////////////////////////////////////////////////////////////////////// * 目次 [#d598aa76] #contents(); /////////////////////////////////////////////////////////////////////////////// * rtags [#aded69fa] - rtags は、llvm をバックエンドに使用したタグ検索システム。 - コンパイラのライブラリを使って解析する為、同名の関数や多重継承でオーバーライドされた関数が複数あっても正しいものに辿り着ける。 - 問い合わせを受けてから解析することもあるらしく、応答が遅いときがある。 - Linux kernel のような巨大なプロジェクトでは、タグ生成の為の情報として使われる json ファイルの生成や問い合わせ時の解析時のパフォーマンスが下がるので、あまり適さない。 - コメント文字列のような、コンパイルに使われないものについては検索出来ない。(cscopeではコメント文字列も検索対象に出来る) - このように、cscope や gtags 等の他のタグシステムとは長所・短所共に異なるので、これらのタグシステムの一つと組み合わせて使うのが良いと思われる。 //============================================================================== ** 環境構築(debian パッケージを使用) [#build-env-debian-package] + 必要な関連パッケージをインストールする # apt-get install rtags + コマンド名はオリジナルから若干アレンジされているので注意(他パッケージとの名前の干渉を避ける為と思われる)。 |>|~コマンド名 | |~オリジナル |~debian パッケージ版 | |rc |rtags-rc | |rdm |rtags-rdm | |rp |rp | -- rc に関しては、9base パッケージの rc コマンドとの重複を避けるためと思われる。 //============================================================================== ** 環境構築(自前ビルド) [#build-env-build] + 必要な関連パッケージをインストールする # apt-get install clang libclang-dev cmake + rtags をビルドする(rtags がディストリビューションでパッケージが用意されているなら、そちらを使うと良い) ++ コードを取得する $ git clone --recursive https://github.com/Andersbakken/rtags ++ ビルドする $ cd rtags $ git submodule init $ git submodule update $ mkdir build $ cd build $ cmake .. $ make $ sudo make install ~ + rtags をインストールする -- ビルドすると rtags/build/bin に以下の実行形式が生成されるので、環境変数 PATH の通っているところに配置する。 $ ls rtags/build/bin rc rdm rp //============================================================================== ** タグを生成する [#u9c384fe] + まず、daemon を起動する $ rdm --daemon + タグを生成する方法は2つある //------------------------------------------------------------------------------ *** 1. rc コマンドに直接渡す [#p77de85a] - 実際に compile するときのコマンドを rc に渡す。 $ rc gcc $(CFLAGS) $(SRCS) //------------------------------------------------------------------------------ *** 2. rc -Jコマンドで compile_commands.json を読み込ませる [#xa2d2a47] - compile_commands.json は、cmake か bear で生成する。 -- bear を使う場合(cmake を使わない、Makefile のみのプロジェクトの場合) --- &color(red){注:下記の make で呼ばれる Makefile で clang を使っていると、後述のコマンド '''"rc -J . "''' を実行したときに失敗することがある模様。その為、Makefile でコンパイラの指定は clang ではなく gcc を使うと良い。}; --- bear コマンドがインストールされていない場合は、インストールする # apt-get install bear --- bear コマンドの実行(環境によっては "--" が不要な場合があるので注意。) $ bear -- make --- 既に compile_command.json があり、且つクリーンビルドでない場合は、 bear に --append オプションが必要(まだ試してはない) -- cmake で生成する場合 ~ T.B.D. - rc -Jコマンドで compile_commands.json を読み込ませる $ rc -J . -- ここでエラーになる場合、compile_commands.json が無意味な内容になっている可能性がある。 --- 原因としては、ビルド済みの環境で bear コマンドを走らせていた可能性がある。 --- 対策としては、make clean してから再度 bear -- make を実行する必要がある。 //============================================================================== ** rtags-rdm の終了 [#ta139a3e] - rdm を終了するには、 rc にて以下のコマンドを実行する: $ rtags-rc -q /////////////////////////////////////////////////////////////////////////////// * emacs から rtags を使う [#f3e74104] //============================================================================== ** emacs の設定 [#b2c2d73e] - rtags.el を、 emacs の load-path の通っているところに置く。rtags.el は、rtag リポジトリの下記にある build/src/rtags.el - rtags の標準のキーバインドは、rtags.el を読み込んだだけでは有効にはならない。読み込んだ後に以下を設定に書く必要がある: (rtags-enable-standard-keybindings); enable rtags standard keymap - submenu-list も、必要なら同様に設定する: (rtags-submenu-list) ; enable rtags submenu list keymap - init.el ;;; rtags.el の設定 (when (require 'rtags nil 'noerror) (when (executable-find "rtags-rc") (setq rtags-rc-binary-name "rtags-rc")) ; debian では rc -> rtags-rc に変更されている (when (executable-find "rtags-rdm") (setq rtags-rdm-binary-name "rtags-rdm")) ; debian では rdm -> rtags-rdm に変更さている (defun rtags-local-conf () (rtags-mode) (rtags-start-process-unless-running) (setq rtags-autostart-diagnostics t) (rtags-diagnostics) (setq rtags-completions-enabled t) (rtags-enable-standard-keybindings) ; enable rtags standard keymap (rtags-submenu-list) ; enable rtags submenu list ;;; キーバインド:ネットでよく見掛ける設定だが、行末コメントの通り他のバインドを上書きしていてあまり良くないので使わない。 ; (local-set-key (kbd "M-.") 'rtags-find-symbol-at-point) ; batting with 'xref-find-definitions' ; (local-set-key (kbd "M-;") 'rtags-find-symbol) ; batting with 'comment-dwim' ; (local-set-key (kbd "M-@") 'rtags-find-references) ; batting with 'mark-word' ; (local-set-key (kbd "M-,") 'rtags-location-stack-back) ; batting with 'xref-pop-marker-stack' ; (local-set-key (kbd "M-<") 'rtags-location-stack-back) ; batting with 'beginning-of-buffer' ; (local-set-key (kbd "M->") 'rtags-location-stack-forward) ; batting with 'end-of-buffer' ;;; キーバインド:実際にはこちらを使う ;;; xcscope.el に操作感を似せつつ、併用出来るようキーバインドが被らないようにしている (local-set-key (kbd "C-c d d") 'rtags-find-symbol-at-point) (local-set-key (kbd "C-c d s") 'rtags-find-symbol) (local-set-key (kbd "C-c d r") 'rtags-find-all-references-at-point) (local-set-key (kbd "C-c d c") 'rtags-find-all-functions-called-this-function) (local-set-key (kbd "C-c d f") 'rtags-find-file) (local-set-key (kbd "C-c d i") 'rtags-symbol-info) (local-set-key (kbd "C-c d m") 'rtags-imenu) (local-set-key (kbd "C-c d t") 'rtags-taglist) (local-set-key (kbd "C-c d C") 'rtags-print-class-hierarchy) (local-set-key (kbd "C-c d <") 'rtags-location-stack-back) (local-set-key (kbd "C-c d >") 'rtags-location-stack-forward) (define-key rtags-mode-map "p" 'rtags-previous-match) (define-key rtags-mode-map "n" 'rtags-next-match) ) (add-hook 'c-mode-common-hook 'rtags-local-conf) (add-hook 'c++-mode-common-hook 'rtags-local-conf) (add-hook 'objc-mode-hook 'rtags-local-conf) ) -- 上記では、Debian / Ubuntu のパッケージで rc, rdm のコマンド名が変更されているのにも対応している。 //============================================================================== ** 機能(一部のみ) [#saa05fe7] - 数多く定義されている API のうち、比較的使う機会の多い一部機能のみ記載する //------------------------------------------------------------------------------ *** rtags-find-symbol-at-point : カーソルが置かれたシンボルの定義を表示する [#w004a611] |~カーソルが指しているもの |~ジャンプ先 |~備考 | |実体やポインタ変数 |定義位置 | | |型名 |型の定義位置 | | //------------------------------------------------------------------------------ *** rtags-print-class-hierarchy : クラス階層構造の表示 [#jdb15cdc] - クラスの型名にカーソルを置いて実行すると、そのクラスの階層構造を表示する - 例 Superclasses: class TestDataB c++/polymorphism/test_data_b.h:6:7: class TestDataB : public TestDataIF class TestDataIF c++/polymorphism/test_data_if.h:4:7: class TestDataIF //------------------------------------------------------------------------------ *** rtags-find-all-references-at-point : 参照元(=呼び出し箇所)を全て表示する [#z198ace6] - xcscope の cscope-find-this-symbol と大体同じ。 //------------------------------------------------------------------------------ *** 検索履歴の移動 [#q15cfd46] - rtags-location-stack-back -- 検索する前の位置に戻る -- 前回検索後からカーソルを移動していた場合、前回検索したときに rtags でジャンプした位置まで戻る。 - rtags-location-stack-forward -- rtags-location-stack-back で1回以上履歴を戻った後、再びその後の検索結果にジャンプする。 -- 当然ながら、一度も rtags-location-stack-back を実行していない場合は動作しない。 //------------------------------------------------------------------------------ *** rtags-taglist [#o67e241d] - 全てのシンボルに関する tag の一覧を表示する /////////////////////////////////////////////////////////////////////////////// * Makefile に rtags 用 tag 生成の target を仕込む(おまけ) [#r52d7a6e] - 下記を Makefile の target として仕込み、 $ make rtags とすれば、tag 生成までの一通りの処理が実行される(但し、 clean ターゲットは別途用意されている前提となる): # for rtags: RTAGS_CMD_RC := /usr/bin/rtags-rc RTAGS_CMD_RDM := /usr/bin/rtags-rdm BEAR_CMD := /usr/bin/bear COMPILE_DB_FILE := compile_commands.json IS_RTAGS_RDM_STARTED := $(shell ls -1 /run/user/$(shell id -u)/rdm.socket 2>/dev/null| wc -l) rtags : rtags-kill-daemon rtags-delete-compile-db clean rtags-start-daemon rtags-create-compile-db rtags-load-compile-db rtags-kill-daemon : ifeq ($(IS_RTAGS_RDM_STARTED),1) pgrep rtags-rdm | xargs kill -KILL; endif rtags-delete-compile-db : $(RMF) $(COMPILE_DB_FILE) rtags-start-daemon : $(RTAGS_CMD_RDM) --daemon; rtags-create-compile-db : $(BEAR_CMD) -- make; rtags-load-compile-db : $(RTAGS_CMD_RC) -J .; /////////////////////////////////////////////////////////////////////////////// * バージョン組み合わせメモ [#v824a60e] |>|>|~version |~distribution |~remark | |~rtags |~rtags.el |~emacs |~|~| |2.38-3 |2.38.130 |27.1 |Debian 11 (bullseye) | | |2.37-1 |2.37.130 |26.3 |Ubuntu 20.04 (focal) | | /////////////////////////////////////////////////////////////////////////////// * linux kernel に使えるか? [#febdfd95] - 対象:linux-6.1.1 - compile_command.json 生成 -- bear コマンドを使ったところ、ビルド開始から json 生成完了までおよそ24時間ほど掛かった。 -- 指定したオプションでコンパイル対象となっていないファイルは compile_command.json にも記載されない為、rtags の検索対象からも外れる。 /////////////////////////////////////////////////////////////////////////////// * 参考リンク [#ib49a8ea] - [[Home · Andersbakken/rtags Wiki · GitHub(開発元 github の wiki)>https://github.com/Andersbakken/rtags/wiki]] - [[最強のC/C++インデクサー "Rtags" を本気で使う>https://qiita.com/kota65535/items/39aa4d6e8adf6ab5f98c]] - [[Rtags で BitVisor の開発を楽になるか?>https://qiita.com/deep_tkkn/items/eb24cb2f0713c7fc4162]]