cscope†
- debian では、 cscope は cscope パッケージに入っている
- ソースコードは Linux ディストリビューションなどが配布しているもの、若しくは開発元の git repository から取得出来る
tag の生成†
- コンソールから
$ cscope-indexer -r
- cscope-indexer のオプション
option | description |
-f <database-file> | 出力先データベースのファイル名を指定する(default: cscope.out) |
-i <list-file> | リストファイル(ファイルのインデックスを記録したファイル)の名前を指定する(default: cscope.files) |
-l | データベースファイルの生成・更新を抑制する。 但し、リストファイルが生成済みであること |
-r | 再帰的にディレクトリを走査する。 このオプションがない場合、走査対象はカレントディレクトリに限定される。 |
-v | 冗長モード |
cscope で SymLink になっているファイルが扱えない問題について†
- ソースコード・ヘッダが SymLink になっている場合、cscope では正しく DB 化出来ない。これは、cscope が DB 作成処理の際、 SymLink を対象外とするように動作する実装になっているためである。
- SymLink も DB 化の対象にしたい場合は、ソースパッケージを取ってきて、以下のように修正する。
- cscope-indexer で SymLink をリスト対象とするように変更する
diff --git a/cscope-15.8a/contrib/xcscope/cscope-indexer b/cscope-15.8a/contrib/xcscope/cscope-indexer
index 13c0ae2..31e3956 100644
--- a/cscope-15.8a/contrib/xcscope/cscope-indexer
+++ b/cscope-15.8a/contrib/xcscope/cscope-indexer
@@ -134,7 +134,7 @@ fi
echo "$DIR/$f"
done
else
- find $DIR \( -type f -o -type l \)
+ find -L $DIR \( -xtype f -o -xtype l \)
fi
) | \
egrep -i '\.([chly](xx|pp)*|cc|hh)$' | \
また、cscope-indexer は内部で環境変数 PATH を独自に設定している(起動したshell の環境変数変数PATHは引き継がれない)ため、下記で修正する cscope の配置先が cscope-indexer から見える場所にあるかどうかを確認しておくこと。
- cscope の中で使われている lstat() を stat() に置き換える
- ソース上の lstat() を全て置き換えてもいいが、configure を走らせる前に config.h.in を1行修正する方がスマート。 HAVE_LSTAT が定義されないようにすれば良い(下記)。
diff --git a/cscope-15.8a/config.h.in b/cscope-15.8a/config.h.in
index 2219be7..b0fff54 100644
--- a/cscope-15.8a/config.h.in
+++ b/cscope-15.8a/config.h.in
@@ -53,7 +53,7 @@
#undef HAVE_LONG_LONG_INT
/* Define to 1 if you have the `lstat' function. */
-#undef HAVE_LSTAT
+// #undef HAVE_LSTAT
/* Define to 1 if you have the `memcpy' function. */
#undef HAVE_MEMCPY
但し、global.h も手直しが必要。
diff --git a/cscope-15.8a/src/global.h b/cscope-15.8a/src/global.h
index cda29aa..1919277 100644
--- a/cscope-15.8a/src/global.h
+++ b/cscope-15.8a/src/global.h
@@ -189,6 +189,7 @@ int rpl_asprintf(char **, const char *, ...);
/* This can happen on only vaguely Unix-ish platforms... */
#ifndef HAVE_LSTAT
+#include <sys/stat.h>
# define lstat(file,buf) stat(file,buf)
#endif
- 修正後、ビルドする
$ configure
$ make
- 実行ファイルをパスの通った所へ配置する。
- パッケージをインストールしている場合は、念の為削除しておいた方が良いだろう。
xcscope.el†
- emacs 上の xcscope.el から tag ファイルを生成する
C-c s L
シンボルを探す†
key | description | remark |
C-c s s | シンボルを指定して探す(定義・呼び出し箇所等の一覧をリストアップする) | |
C-c s C | 指定したシンボルの呼び出し箇所をリストアップ | |
C-c s G | 指定したシンボルの定義(宣言ではなく)、またはそれに関する定義をリストアップする | |
C-c s n | 次のシンボルへ Jump | |
C-c s p | 前のシンボルへ Jump | |
xcscope のキーバインド一覧(xcscope.el ver.1.0)†
;; * Keybindings:
;;
;; All keybindings use the "C-c s" prefix, but are usable only while
;; editing a source file, or in the cscope results buffer:
;;
;; C-c s s Find symbol.
;; C-c s = Find assignments to this symbol
;; C-c s d Find global definition.
;; C-c s g Find global definition (alternate binding).
;; C-c s G Find global definition without prompting.
;; C-c s c Find functions calling a function.
;; C-c s C Find called functions (list functions called
;; from a function).
;; C-c s t Find text string.
;; C-c s e Find egrep pattern.
;; C-c s f Find a file.
;; C-c s i Find files #including a file.
;;
;; These pertain to navigation through the search results:
;;
;; C-c s b Display *cscope* buffer.
;; C-c s B Auto display *cscope* buffer toggle.
;; C-c s n Next symbol.
;; C-c s N Next file.
;; C-c s p Previous symbol.
;; C-c s P Previous file.
;; C-c s u Pop mark.
;;
;; These pertain to setting and unsetting the variable,
;; `cscope-initial-directory', (location searched for the cscope database
;; directory):
;;
;; C-c s a Set initial directory.
;; C-c s A Unset initial directory.
;;
;; These pertain to cscope database maintenance:
;;
;; C-c s L Create list of files to index.
;; C-c s I Create list and index.
;; C-c s E Edit list of files to index.
;; C-c s W Locate this buffer's cscope directory
;; ("W" --> "where").
;; C-c s S Locate this buffer's cscope directory.
;; (alternate binding: "S" --> "show").
;; C-c s T Locate this buffer's cscope directory.
;; (alternate binding: "T" --> "tell").
;; C-c s D Dired this buffer's directory.
;;
xcscope のキーバインドが正しく動作しない場合†
参考リンク†
acscope.el†
- ascope.el は cscope の emacs 用 I/F の一つ。
- xcscope.el と比べて
- 機能は少ない
- xcscope.el と違って毎回検索を行わない分、
- 結果表示までの時間は早い
- 対象のソースコードに変更があった場合、検索結果に正しく反映されない場合がある
- debian では、 cscope は cscope パッケージに入っている
- この他、 emacs で使用するのに acscope.el を使う。debian8 にはパッケージはない。
- debian8 のようにディストリビューションからパッケージが提供されていない場合は、GitHub または EmacsWiki などから Download して組み込む。
但し EmacsWiki に掲載されているものは、 GitHub の最新版より大分古いようなので注意が必要。
- キーバインドを設定する
- ascope.el ではキーバインドが設定されてない一方、関数名が xcscope.el と同じなので、xcscope.el から流用して設定する。
#ただ、xcscope.el にあって ascope.el にないものが多い。
(setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/ascope") load-path))
(load-library "~/.emacs.d/site-lisp/ascope/ascope.el")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Original is from xcscope.el
(defvar cscope-minor-mode-keymap
(let ((map (make-sparse-keymap)))
;; xemacs has various issues with (cscope-mouse-popup-menu-or-search), so I
;; don't use that function for xemacs. Its popup menu support won't be as
;; good (cscope will still prompt for the search term)
;(if cscope-running-in-xemacs
; (progn
; (define-key map [(shift button3)] 'cscope-mouse-search-again))
; (define-key map [mouse-3] 'cscope-mouse-popup-menu-or-search)
; (define-key map [S-mouse-3] 'cscope-mouse-search-again))
;; The following line corresponds to be beginning of the "Cscope" menu.
(define-key map "\C-css" 'cscope-find-this-symbol)
(define-key map "\C-csd" 'cscope-find-global-definition)
(define-key map "\C-csg" 'cscope-find-global-definition)
; (define-key map "\C-csG" 'cscope-find-global-definition-no-prompting)
; (define-key map "\C-cs=" 'cscope-find-assignments-to-this-symbol)
(define-key map "\C-csc" 'cscope-find-functions-calling-this-function)
(define-key map "\C-csC" 'cscope-find-called-functions)
(define-key map "\C-cst" 'cscope-find-this-text-string)
; (define-key map "\C-cse" 'cscope-find-egrep-pattern)
(define-key map "\C-csf" 'cscope-find-this-file)
(define-key map "\C-csi" 'cscope-find-files-including-file)
;; --- (The '---' indicates that this line corresponds to a menu separator.)
; (define-key map "\C-csb" 'cscope-display-buffer)
; (define-key map "\C-csB" 'cscope-display-buffer-toggle)
; (define-key map "\C-csn" 'cscope-history-forward-line-current-result)
; (define-key map "\C-csN" 'cscope-history-forward-file-current-result)
; (define-key map "\C-csp" 'cscope-history-backward-line-current-result)
; (define-key map "\C-csP" 'cscope-history-backward-file-current-result)
; (define-key map "\C-csu" 'cscope-pop-mark)
;; ---
; (define-key map "\C-csa" 'cscope-set-initial-directory)
; (define-key map "\C-csA" 'cscope-unset-initial-directory)
;; ---
; (define-key map "\C-csL" 'cscope-create-list-of-files-to-index)
; (define-key map "\C-csI" 'cscope-index-files)
; (define-key map "\C-csE" 'cscope-edit-list-of-files-to-index)
; (define-key map "\C-csW" 'cscope-tell-user-about-directory)
; (define-key map "\C-csS" 'cscope-tell-user-about-directory)
; (define-key map "\C-csT" 'cscope-tell-user-about-directory)
; (define-key map "\C-csD" 'cscope-dired-directory)
;; The previous line corresponds to be end of the "Cscope" menu.
;; (START Add) --------------------------------------
;; ここは xcscope.el にないものを追加
(define-key map "\C-csa" 'cscope-setup)
;; (END Add) --------------------------------------
map)
"The global cscope keymap")
(require 'ascope)
tagの生成†
参考リンク†
参考リンク†
id-utils†
- debian の場合は、以下のパッケージをインストールする
id-utils elscreen
- emacs
emacs の設定†
DB の生成†
symbol の検索†
gtags / global の利用†
- タグシステムの一つ
- debian では、 global パッケージに入っている
tag の生成†
$ gtags [options] [path]
$ gtags -f <files>
$ gtags -v
- gtags には、etags と違って append mode が存在しないため、xargs でマルチスレッド化して実行するのは不可かもしれない。
- -f <file> を指定しない場合、gtags はカレント以下のディレクトリを走査してタグ情報を生成する。
- tag の生成処理が終わると、実行したディレクトリ配下に、下記4つのファイルが作られる:
GPATH GTAGS GRTAGS GSYMS
emacs の設定†
- gtags.el を入手する
- キーバインドを設定する
; "\M-p" が prefix-command に喰われていて使えないので、全て "\C-\M-" のシリーズにしている
(global-set-key "\C-\M-t" 'gtags-find-tag) ;関数の定義元へ
(global-set-key "\C-\M-r" 'gtags-find-rtag) ;関数の参照先へ
(global-set-key "\C-\M-s" 'gtags-find-symbol) ;変数の定義元/参照先へ
(global-set-key "\C-\M-p" 'gtags-find-pattern)
(global-set-key "\C-\M-f" 'gtags-find-file) ;ファイルにジャンプ
(global-set-key [?\C-,] 'gtags-pop-stack) ;前のバッファに戻る
参考リンク†
etags (ctags for Emacs)の利用†
tag の生成†
- まずは、 Tag file を生成する。emacs パッケージには etags.emacs** なコマンドが付属している場合があるので、それがあればそちらを使う。
- Tag file は TAGS というファイル名で生成される。
$ etags.emacs23 `find | grep -i "\.c$\|\.cc\|\.cpp$\|\.cxx$\|\.h$"
- ただ、ファイル数が多い場合にはコマンドラインバッファの上限を超えてしまい、全てのファイルを処理できないことが予想される。この問題は xargs を使って解消することが出来る。
以下に、そのためのスクリプトを示す。
下記の例では、 xargs の -P オプションも併用し、マルチスレッドで動作するようにしている。 THREAD_NUM は CPUの数もしくは Core 数に合わせる。
#!/bin/bash
TAGS_FILE=TAGS
CMD_ETAGS=etags.emacs23
THREAD_NUM=4
rm -f ${TAGS_FILE};
find | grep -i "\.c$\|\.cc\|\.cpp$\|\.cxx$\|\.h$" | xargs -P ${THREAD_NUM} -I {} ${CMD_ETAGS} -a {} # 対象となるソース・ヘッダを etags に引数で渡す
- 全てのファイルを渡すのにコマンドバッファが足りなくなってしまう場合(=ファイル数が多い場合や個々のパス名が長い場合など)でも全てのファイルを渡せるよう、xargs を使って etags にファイル名を渡すようにしている。
- コマンドバファが足りなくなった場合、 xargs は複数回 etags を呼ぶ。この場合、 etags が append モードで動作しないと etags は呼ばれる度に TAGS ファイルを上書きしてしまうので注意すること(そのため上記では append モードにするため "-a" を付けて etags を呼んでいる)。
emacs に TAGS ファイルを読みこませる†
M-x: tags-reset-tags-tables 一旦リセットする
M-x: visit-tags-table 明示的に TAGS ファイルを読み込む
- emcs から操作する(下記)
Key binding | command | description |
M-. | find-tag | クラスや関数を探す |
C-u M-. | | 次の検索結果候補を表示する |
C-u – M-. | | 前の検索結果候補を表示する |
M-* | | 元の場所に戻る |
C-x 4 . | find-tag-other-window | タグ(名前)の定義箇所を探し別ウィンドウに表示 |
C-x 5 . | find-tag-other-frame | タグ(名前)の定義箇所を探し別フレームに表示 |
ctags-exuberant†
- 正しくは、Exuberant ctags という。このページ名は、Debian のパッケージ名に合わせている。
- ctags の派生プログラムである。
- install 後、実行ファイルは /usr/bin/ctags-exuberant に配置される。システムによっては /usr/bin/ctags に symlink されることもある。
debian 8 にはパッケージが存在しない。 → exuberant-ctags というパッケージになっている。
TAGS file の生成†
$ ctags-exuberant -e -R [path]
- これにより、 'TAGS' という名前のファイルが生成される。
- emacs からの使い方は、etags と基本的に同じ
emacs から TAGS の生成を行えるようにする†
参考リンク†
ebrowse (ebrowse for Emacs)の利用†
Links†
SilentBob†
tag の生成†
$ bob --make-ctags
$ bob --cfiles
$ bob -L cfiles --call-tags
参考リンク†
各システムでの解析速度†
- 各タグシステムで同一コードツリーを走査して、 DB を作り終わるまでの時間を計測した。
- 計測結果は何れも、ディスクアクセスの影響がない状態でのものとなっている(tmpfs上に展開したコードツリーを走査対象としている)
- 対象:linux-3.16.36
- 結果:
Tag System | command | elapsed time [sec] | remark |
cscope | cscope-indexer -r | 20.19 | |
id-utils | mkid | 19.23 | |
gtags-global | gtags | 25.24 | |
etags | find | grep -i "\.h$\|\.c$|\.cc$|\.cxx$|\.cpp" | xargs -P ${THREAD_NUM} -I {} etags -a {} | 35.69 | THREAD_NUM=4 because CPU of system has 4 cores. |
ctags-exuberant | ctags-exuberant -e -R <path> | 16.36 | |
Silent Bob | bob --make-ctags bob --cfiles bob -L cfiles --call-tags | 22.79 | |