原文:
Using Cscope on large projects (example: the Linux kernel)
http://cscope.sourceforge.net/large_projects.htmlTranslated by Bob
2012-4-28
Email:
gexbob@gmail.comBlog:
http://blog.csdn.net/exbob 如果你要涉及一個(gè)大的代碼庫(kù),Cscope 會(huì)是一個(gè)非常有用的工具. 它可以通過(guò)快速、有目的的搜索為你節(jié)省很多時(shí)間,而不是像 grep 那樣隨機(jī)的對(duì)源文件手動(dòng)搜索(對(duì)于大的代碼庫(kù),grep 需要一段時(shí)間才能啟動(dòng)).
在這個(gè)教程中,你將學(xué)會(huì)如何針對(duì)一個(gè)大項(xiàng)目來(lái)設(shè)置 Cscope. 我們用到的例子是 Linux 內(nèi)核源代碼, 基本的步驟和其他大項(xiàng)目是一樣的, 包括 C++ 和 JAVA 項(xiàng)目.
1.獲取源代碼. 首先要獲取源代碼. 可以從
http://www.kernel.org 下載內(nèi)核源代碼. 本教程中假設(shè)你下載的是 Linux 2.4.18 并且安裝在 /home/jru/linux-2.4.18.
注意: 確保你有足夠的磁盤空間: 內(nèi)核壓縮包只有 30 MB, 解壓后會(huì)的源代碼是 150 MB , 生成的 Cscope 數(shù)據(jù)庫(kù)會(huì)占用額外的 20-100+ MB (這取決于你想要數(shù)據(jù)庫(kù)包含多少內(nèi)核代碼). 有必要的話,可以把源代碼和 Cscope 數(shù)據(jù)庫(kù)放在兩個(gè)不同的磁盤分區(qū) .
2.弄清楚你想要把 Cscope 數(shù)據(jù)庫(kù)文件放在哪里. 我假設(shè)你會(huì)在 /home/jru/cscope 存放數(shù)據(jù)庫(kù)和關(guān)聯(lián)文件.
3.生成一個(gè)帶有瀏覽文件列表的 cscope.files . 對(duì)于某些項(xiàng)目, 你可能想要在 Cscope 數(shù)據(jù)庫(kù)中包含項(xiàng)目目錄中的所有 C 源文件. 這種情況下可以跳過(guò)這一步, 只需在項(xiàng)目的頂層目錄上執(zhí)行 'cscope -R' 來(lái)構(gòu)建你的 Cscope 數(shù)據(jù)庫(kù). 但是如果有些代碼你不想包含, 或者你的項(xiàng)目包含 C++ 或 JAVA 源代碼 (Cscope 默認(rèn)只能解析 .c, .h, .y, 或 .l 文件), 就要生成一個(gè) cscope.files 文件, 其中包含了想要 Cscope 掃描的所有文件名 (每個(gè)文件名占一行).
你有可能用到絕對(duì)路徑 (至少在編輯器里使用 Cscope 數(shù)據(jù)庫(kù)時(shí)需要), 這樣就可以在你創(chuàng)建的目錄之外使用數(shù)據(jù)庫(kù). 我展示的命令會(huì)先進(jìn)入根目錄, 這樣就可以用 find 打印出絕對(duì)路徑.
對(duì)于很多項(xiàng)目, find 命令可以這樣用:
[plain]
view plaincopycd /
find /my/project/dir -name '*.java' >/my/cscope/dir/cscope.files
對(duì)于 Linux 內(nèi)核, 就有點(diǎn)棘手, 因?yàn)槲覀兿胍懦臋n和腳本目錄下的代碼, 還有除 Intel x86 外的所有芯片和體系結(jié)構(gòu)的匯編代碼(我想你的體系結(jié)構(gòu)是 X86). 另外, 本例中我會(huì)排除所有的內(nèi)核驅(qū)動(dòng)代碼 (這些代碼超過(guò)要解析的代碼總量的兩倍, 會(huì)導(dǎo)致 Cscope 數(shù)據(jù)庫(kù)膨脹, 并且包含了很多重復(fù)的定義, 通常更難搜素. 如果你對(duì)驅(qū)動(dòng)代碼感興趣, 可以省略下面相關(guān)的行, 或者修改為只輸出你感興趣的驅(qū)動(dòng)文件):
[plain]
view plaincopyLNX=/home/jru/linux-2.4.18
cd /
find $LNX \
-path "$LNX/arch/*" ! -path "$LNX/arch/i386*" -prune -o \
-path "$LNX/include/asm-*" ! -path "$LNX/include/asm-i386*" -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 >/home/jru/cscope/cscope.files
這里用到了find 命令, 在大項(xiàng)目中,這樣做比手動(dòng)編輯一個(gè)文件列表容易多了, 也可以從其他地方復(fù)制一個(gè).
4.生成 Cscope 數(shù)據(jù)庫(kù). 到了生成 Cscope 數(shù)據(jù)庫(kù)的時(shí)候了:
[plain]
view plaincopycd /home/jru/cscope # the directory with 'cscope.files'
cscope -b -q -k
-b 選項(xiàng)告訴 Cscope 只要構(gòu)建數(shù)據(jù)庫(kù),無(wú)需啟動(dòng) Cscope GUI. -q 會(huì)導(dǎo)致一個(gè)額外的'inverted index' 文件被創(chuàng)建, 它會(huì)使大數(shù)據(jù)庫(kù)的搜索更快. 最后, -k 設(shè)置 Cscope 為 'kernel' 模式——這樣它就不會(huì)去 /usr/include 下搜索源文件中包含的頭文件 (這是在操作系統(tǒng)或 C 源碼庫(kù)中使用 Cscope 時(shí)的主要作用).
在我的 900 MHz Pentium III 系統(tǒng)上 (帶一個(gè)標(biāo)準(zhǔn)的 IDE 硬盤), 解析這樣的 Linux 源碼只用了 12 秒, 輸出的 3 個(gè)文件 (cscope.out, cscope.in.out, 和 cscope.po.out) 總共占用了 25 MB.
5.使用數(shù)據(jù)庫(kù). 如果你喜歡用 vim 或 emacs/xemacs, 我建議你先學(xué)習(xí)怎樣在這些編輯器中使用 Cscope, 這樣才能讓你在編輯器中輕松的運(yùn)行搜索. 我們有一份 tutorial for Vim, emacs 用戶當(dāng)然是足夠聰明的,可以根據(jù) cscope/contrib/xcscope 目錄下的寶貴意見(jiàn)來(lái)解決所有問(wèn)題.
否則, 你可以用獨(dú)立的基于 curses 的 Cscope GUI 來(lái)運(yùn)行搜索, 然后啟動(dòng)你喜歡的編輯器(無(wú)論 $EDITOR 設(shè)為什么,或默認(rèn)是vi) 來(lái)打開(kāi)搜索結(jié)果中的行.
如果你用獨(dú)立的 Cscope 瀏覽器, 確保這樣調(diào)用它:
[plain]
view plaincopycscope -d
這樣 Cscope 就不會(huì)重新生成數(shù)據(jù)庫(kù). 否則你就不得不 Cscope 檢測(cè)修改過(guò)的文件, 在大項(xiàng)目中會(huì)花很多時(shí)間, 即使沒(méi)有文件被修改過(guò). 如果偶然沒(méi)有帶任何參數(shù)就運(yùn)行了 'cscope', 也會(huì)導(dǎo)致重新創(chuàng)建沒(méi)有快速索引和內(nèi)核模式的數(shù)據(jù)庫(kù), 那就要重新運(yùn)行之前的 cscope 命令了.
6.源碼改變時(shí)重新生成數(shù)據(jù)庫(kù).
如果項(xiàng)目中有了新文件, 就再運(yùn)行 'find' 命令來(lái)更新 cscope.files (如果正在使用它).
像初始生成數(shù)據(jù)那樣,用同樣的方法調(diào)用 cscope (并且在相同的目錄下) (即, cscope -b -q -k).
Tutorial by Jason Duell