2009年1月20日 星期二

使用cscope 取代 source insight 以瀏覽 kernel source





解決linux下代碼查看問題

在 Windows 下面我們有 Source Insight 可以方便的瀏覽大工程中的代碼,切換到 Linux 環境下開發時, 我們也可以搭建一個這樣的環境。下面的內容將介紹如何搭建這樣一個開發環境(這裡我們假設讀者已經熟悉 emacs 的安裝和配置)。
  步驟一安裝下列軟件
 
 1)cscope :cscope是一個代碼瀏覽工具,它可以幫你在一個大的工程中,
快速定位到一個函數/變量的聲明位置,所有引用地方等,它可以結合vim和emacs一起使用。
單獨使用cscope時不同文件間的跳轉變得很難處理,這裡我們介紹cscope在emacs環境中的使用,它需要預先建立索引檔:根據
cscope.files 的內容來建立索引:cscope.[in][out]。

  步驟二修改或創建.emacs文件
  ;;加載我們需要的plugin (使用cscope的必備動作)
(load-file "/usr/share/emacs/site-lisp/xcscope.el")
(require 'xcscope)
(setq cscope-do-not-update-database "t")
  ;; 這行後面會解釋
(setq cscope-set-initial-directory "./")  ;; 在現有目錄下找 cscope.out

      步驟三添加工程:
  假設我們要把/home/tom/src/linux-2.6.23的源代碼做出cscope索引,我們可以這樣做,

       #>make ARCH=arm cscope  這裡 ARCH 可以等於 arm, x86, mips,  ...等等你想要的 CPU arch。

       手動自己來:

  1)#>cd /home/tom/src/linux-2.6.23 進入源代碼根目錄;
  2)#>touch cscope.sh 創建一個腳本文件,內容如下

#!/bin/bash
LNX=`pwd`
ARCH=arm
cd /
find $LNX/ \
-path "$LNX/arch/*" ! -path "$LNX/arch/$ARCH*" -prune -o \
-path "$LNX/include/asm-*" ! -path "$LNX/include/asm-$ARCH*" -prune -o \
-path "$LNX/tmp*" -prune -o \
-path "$LNX/Documentation*" -prune -o \
-path "$LNX/scripts*" -prune -o \
-path "$LNX/drivers*" -prune -o \
-name "*.[chxsS]" -print >$LNX/cscope.files
find $LNX/ -path "$LNX/include/asm-generic*" -name "*.[chxsS]" -print >> $LNX/cscope.files

 然後 #>cscope -b -k -q ( -q 是建立雙向鏈結,可增加搜尋速度!),這時候要等個幾分鐘,等待索引的建立!因為針對 ARCH=arm 來做,所以建出以 arm 為主的索引檔。

    成功後執行 cscope.sh 腳本。

  步驟四:關於cscope代碼瀏覽命令
            C-c s a 設定初始化的目錄(cscope-set-initial-directory) ,一般是你代碼的根目錄,為了省事,我們可以把這一行命令在進入 emacs 就執行,像剛剛的 .emacs 範例一樣。
       鬼 C-c s I (i 大寫) 對目錄中的相關文件建立列表並進行索引。內定會自動建立索引。記得嗎?我們剛剛做過索引了,並用 -q 參數,所以這裡不但不要用這個指令,(在 emacs 外面用 -q 建索引就好),還應該要 disable 自動建索引的功能,因為在 emacs 裡面會主動呼叫 cscope 建立索引。所以剛剛我們修改了(setq cscope-do-not-update-database "t")。

若不這樣改,在自動建立索引時會抱怨 -q 與 database 不合的警告,重建的 database 也將喪失雙向搜尋的能力,用起來會變得蠻慢的喔!因為 kernel symbol 實在太多了!

            C-c s s 序找符號
            C-c s g 尋找全局的定義(即是 cscope-find-global-definition)
            C-c s c 看看指定函數被哪些函數所調用
            C-c s C 看看指定函數調用了哪些函數
            C-c s e 尋找正則表達式
            C-c s f 尋找文件
            C-c s i 看看指定的文件被哪些文件include
            C-c s u 回到上一個 symbol  (即cscope-pop-mark)

結論:Source Insight 雖然直覺好用,但是你還得找到 Windows 環境才能 run,用wine 模擬 Windows 是一個辦法啦!這裡只是提供了『純 Linux 環境』的做法,供大家參考!

補充:用 etags 配合使用,更方便:(假設已經裝好 ctags 套件)       

       1)   在進入 emacs 之前先用 etags -R 建立 TAG 檔。
在 emacs 裏面的指令:
       2)   M-x visit-tags-table 會詢問是否用 default TAG file? 按 y 即可。
       3)   M-. 找定義,以游標所在位置的變數來找。
       4)   M-* 返回。
       5)   C-u M-. 尋找標籤的下一個定義。


補充:修改 .emacs 取代常用的 cscope 命令,在 (require 'xcscope) 後加上
(define-key global-map [f5] 'cscope-find-this-file)
(define-key global-map [f6] 'cscope-find-this-symbol)
(define-key global-map [f7] 'cscope-pop-mark)
(define-key global-map [f8] 'cscope-find-global-definition)
(define-key global-map [f9] 'cscope-find-global-definition-no-prompting)
(define-key global-map [M-up] 'cscope-prev-symbol)
(define-key global-map [M-down] 'cscope-next-symbol)
(define-key global-map [f12] 'c-down-conditional-with-else)
(define-key global-map [M-f12] 'c-up-conditional-with-else)

這樣,就可以用 F5, F6, F7, F8, F9 Esc-↑ Esc-↓ 來 browse code,您可以把常用的 key 如法泡製。