株式会社シジャム・ビーティービー

Tools

ソースコードを読むための環境整備

普段からほとんど Linux 上で生活してますが、特にソースコードを読んだり書いたりする時には以下のソフトを使用しています。

xemacs (emacsen), ctags, global, quilt, git

これらは Fedora Core 5 (FC5) なら Extras にあるので yum install すれば簡単にインストールできます。以下はソースコード (特に Linux kernel) を読む場合に便利な設定例です。

ctags (Exuberant Ctags)

global にも当然 parser はありますが、ctags を使うと構造体の型の定義自体にも跳べるようになるので global の parser として使ってます (cscope とかでも可能かもしれませんが、、)。これがあるのとないのとでは、特に Linux kernel のような巨大ソースコードでは大違いです。

ただ、ctags を使用すると、Linux kernel のソースコードの一部をうまく解析できなくなります (gtags-parser を使用する場合は大丈夫)。

kernel/sched.c:

static inline runqueue_t *task_rq_lock(task_t *p, unsigned long *flags)
    __acquires(rq->lock)

static inline void task_rq_unlock(runqueue_t *rq, unsigned long *flags)
    __releases(rq->lock)

__acquires, __releases の部分なんですが、ctags 実行時のオプションを指定することで対策できます (実際には global の設定ファイルで指定してます)。

他にも ./drivers/scsi/oktagon_io.S の解析にも失敗しますが、こちらは重要ではないので global の設定ファイルで対象から除外します。

global

最近ではメジャーになってきたので説明不要かと、、ググれば沢山説明がありますが、ここでは ctags, xemacs, quilt, git と併用する場合の設定 (.globalrc) を載せておきます。

#
# default target を変更
#
default:\
        :tc=ctags-devel:tc=htags:
#
# .git, .pc, patches, ./drivers/scsi/oktagon_io.S を tags 作成対象から外す
#
common:\
        :skip=GPATH,GTAGS,GRTAGS,GSYMS,HTML/,html/,tags,TAGS,ID,y.tab.c,y.tab.h
,.notfunction,cscope.out,.gd
binit,SCCS/,RCS/,CVS/,CVSROOT/,{arch}/,.svn/,.cvsrc,.cvsignore,.cvspass,.cvswrappers,.deps/,autom4te.cache/
,.snprj/,.git/,.pc/,patches/,oktagon_io.S:\

# デフォルトで用意されている ctags-exuberant target を元に ctags-devel
# target を作ります。違いは以下
# o 関数定義を解析する parser として ctags を使用
# o 構造体の型名等も対象となるように ctags のオプションを指定
# o __acquires, __releases 対策
# o 参照とシンボルのデータも作成
ctags-devel|Exuberant Ctags|ctags by Darren Hiebert:\
        :tc=common:\
        :suffixes=s,a,sa,asm,C,H,cpp,cxx,hxx,hpp,cc,c,h,y,S,inc:\
        :extractmethod:\
        :GTAGS=/usr/bin/ctags -I __acquires+ -I__releases+\
                --c-types=fdst --asm-types=fl -x %s | perl -ne '\
                if (/^operator \\S+\\s+function\\s/) { s/^operator //; }\
                ($name, $type, $no, $path, $line) = split(/[ \\t]+/, $_, 5);\
                printf(STDOUT "%-16s %4d %-16s %s", $name, $no, $path, $line);':\
        :GRTAGS=gtags-parser -dtr %s:\
        :GSYMS=gtags-parser -dts %s:

xemacs (emacsen)

global 付属の gtags.el を使用することで、マウスクリックで跳ぶことができるようになりますが、定義、参照、シンボルに関して明示的に跳べるようにするため、以下のように .xemacs/init.el (emacs なら .emacs) に設定してます。

(setq gtags-mode-hook
      '(lambda ()
         (if (not gtags-running-xemacs) nil
           (define-key gtags-mode-map 'button2 'gtags-find-tag)
           (define-key gtags-mode-map '(shift button2) 'gtags-find-rtag)
           (define-key gtags-mode-map '(control button2) 'gtags-find-symbol))
         (if gtags-running-xemacs nil
           (define-key gtags-mode-map [mouse-2] 'gtags-find-tag)
           (define-key gtags-mode-map [S-mouse-2] 'gtags-find-rtag)
           (define-key gtags-mode-map [C-down-mouse-2] 'gtags-find-symbol)
           (define-key gtags-mode-map [C-mouse-2] 'gtags-find-symbol))
         ))

こうすることで、真ん中ボタンクリックで実体へ、シフト押しながら真ん中ボタンで参照へ、コントロール+真ん中ボタンでシンボルへ跳べるようになります。
emacs 用の設定では [C-down-mouse-2] と [C-mouse-2] を設定していますが、実はよくわかってなくて、試行錯誤の結果こうなってます。

quilt

もともとは Andrew Morton が開発していた?バージョン管理ツールです。これの良い所は、複数の patch を適用したり、はずしたり、任意の patch を変更したりが簡単に出来る所です。BSC にある Cell 用の Linux kernel patch もこれで管理されています。特別な設定はしていません。

git

upstream の linus tree や -mm 等がこれで管理されています。ホントは upstream との比較を簡単にできるように quilt じゃなく、git (stgit) を使いたい所です。git-quiltimport というコマンドがあるので quilt から git への移行は簡単にできそうですが、、、後日やってみようかな、、