2010年6月3日 星期四

用 vim 有效閱讀 Android framework 程式碼

Android 發展至今,程式碼的部份不斷的膨脹,越來越大。要整個通透需要花點時間,而這篇文章主要是談論如何利用 vim 來快速閱讀 Android 程式碼,這邊的程式碼包含底層 C , C++ and Java framework 的部份,當然如果你是寫 Application 的人,也許用 Eclipse 會快一點,不過如果你想了解 Android framework 的實作也可以透過下面的方式去瀏覽。

請自我確認一下,如果你有下面幾個症狀,請務必看完這篇文章,應該對你很有幫助。
  1. 如果你還在用 grep 找 key word
  2. 如果你還在開多個 tab 然後下指令,去開某個含有特定 key word 的源碼
  3. 如果你很勤勞的想每個檔案都打開看完,並了解所有 class or object 特性
如果你沒有這樣的症狀,那您可以省下寶貴時間不用看下面的文章。



先說明幾個狀況:
  1. Android 下有幾個超大單一檔案程式碼,行數超過 8xxx 到 1xxxx 行
  2. 有 Java + JNI + C/CPP + AIDL 程式碼, *.mk 等 build system 檔案,多采多姿的檔案類別
  3. 有些部分還透過 python 去產生 dummy code 然後一起 compile  
  4. 檔案數量很大,程式碼不含 GCC 約有 1~ 1.2G (source code)
沒錯!你沒看錯,上面就是 Android 程式碼的狀況。所以沒有軟體輔助,你應該會眼泛淚光,黑眼圈滿堂。

其實用 Source Insight 就可以解決這樣的問題,但是很貴,用盜版又覺得很沒有開源精神,基於這樣的方式,我們應該可以尋找類似的解決方案,不期待全部解決,但至少可以解決一半。

其實,在我之前寫的 multi-projects of vim using cscope plugin,就可以解決這樣的問題。

但是請修改 goproj.sh 的內容,內容如下(主要加入幾個會參考到的附檔名)
CSCOPE_FILE=cscope.out
if [ -n "$1" ]; then
 echo "Source code directory: " $1
 echo "Create file map : " $CSCOPE_FILE
 find $1 -name "*.aidl" -o -name "*.cc" -o -name "*.h" -o -name "*.c" -o -name "*.cpp" -o -name "*.java" -o -name "*.mk" > $CSCOPE_FILE
 cscope -bkq -i $CSCOPE_FILE
 ctags -R --exclude=.svn
else
 echo "Please key-in path of project"
fi

請花點時間,試試下面幾個鍵(按下組合鍵前,移動游標到你想找的 function 上,然後再按下組合鍵)

[ Ctrl + \ + s ] : 搜尋游標上的 function 哪邊參考到
[ Ctrl + \ + c ] : 搜尋游標上的 function 哪邊呼叫到
[ Ctrl + \ + g ] : 搜尋游標上的 function 是在哪邊定義的

上面三個組合鍵,都會在 vim 跑出一個 list ,你可以透過輸入數值決定你要跳到哪個檔案中的哪一行定義上去。你也可以一目了然這個 function 被誰呼叫到,或是使用到。只要一個數字鍵,馬上跳到哪個檔案的那一行去,不需要切換視窗。當然,你會想回到原本編輯的檔案去看相關的程式碼,那也可以,請用下面兩個組合鍵。


[ Ctrl + \ + t ] : 跳回下一個位置
[ Ctrl + \ + o ] : 跳回上一個位置

以上的方式幾乎可以滿足,看程式碼基本的要求,速度上也不慢。不過唯一的缺點就是,在建立cscope.file (function search index)的部份需要先跑過一次,而如果檔案有變動,這 index 是不會自動更新的,你需要在下一次指令去建立新的 index file。不過這樣並不會影響到使用狀況,雖然 index 資料是舊的,但還是會自動跳到原本的位置,只是可能位置上會有些位移,透過 search key word 的方式應該就可以彌補。

相信這樣的方式,會讓你看程式碼的速度快上 2.5x (哈!是 JIT 的功勞嗎? ),我個人使用感覺是很有效率,節省很多 grep 的時間,也更精準可以知道程式碼的流向。


期待嗎?趕快 try 看看吧!

2011/02/18 Update:
已經將上面的 script (multi-cscope-db) 放到 github 去,有需要的自行取用吧!
git clone git@github.com:charz/multi-cscope-db.git

2014/03/25 Update:

http://blog.chhsu.org/2014/03/vim-multiple-cscope-db.html

6 則留言:

steveoreo 提到...

不知閣下有否使用ctags? 小弟是用ctags, parse一次所有代碼,就可以像看vim help一樣用ctrl+] 自動跳進某一keyword 所對應的代碼檔

Char 提到...

ctags -R --exclude=.svn
其實在文中就有提到是用ctags + cscope。
ctags在用的時候還是覺得有些不足,在加上cscope就可以補足ctages的缺點。

建議try看看,很不錯用。

shawn 提到...

很實用的方法:)
不過find那行有問題, 少加了幾個-o, 副檔名之間要用
-o把-name串起來, 不然會找不出該副檔名的檔案.

Char 提到...

Hi, shawn,

這部份我已經修正了,其實之前已經發現,只是忘記更新blog文章。
感謝您的提醒。

Kuan-Po Huang 提到...

作者你好,

請問是否有遇過cscope掃檔案的時候
發生cannot find file xxxx的問題呢?
我有試著去加" "
但問題一樣發生

謝謝

Char 提到...

hi Kuan Po Huang,
你會出現那個問題代表, 相對的路徑找不到。因為cscope在產生db的時候,是利用相對路徑,所以你要開檔案的時候,如過從另一個目錄去開上層目錄其他檔案就會有問題。

而我修改過得部份是改成絕對路徑,所以應該不會有問題。你可以在嘗試看看!:)