看源代碼是一個程式員必須經曆的事情,也是可以提升能力的一個捷徑。個人認為: 要完全掌握一個軟體的方法隻有閱讀源碼。
在windows下有sourceinsight這個源碼閱讀軟體(雖然我沒用過,但是網上評價還不錯),由于我是個linuxer,并不喜歡用windows,是以自然是選擇在linux下閱讀源碼的工具了。
下面我将逐一介紹在linux下閱讀源碼的工具。

<a target="_blank"></a>
源碼閱讀三劍客:vim配合ctags和cscope,足以在源代碼裡面自由翺翔,在函數和變量間自由跳轉。
<code>sudo apt-get install vim ctags cscope</code>
ctags的使用很簡單,vim已經内置了對ctags的支援。
首先在源代碼根目錄執行<code>ctags -r</code>,遞歸的為源碼建立tags,在根目錄會生成一個tags的檔案,存放各種函數和變量的tag,便于跳轉:
使光标在函數或變量上,<code>ctrl + ]</code>即可跳轉到其定義處
<code>ctrl + t</code>可以回到你跳轉之前的位置
對于簡單的代碼,ctags就夠用了,但是對于比較複雜的代碼來說,ctags顯得有點力不從心,于是,下一位劍客就登場了。
vim同樣内置了對cscope的支援。
首先在源代碼根目錄執行<code>cscope -rbq</code>,就會生成cscope.out檔案(索引資料庫)
-r: 在生成索引檔案時,搜尋子目錄樹中的代碼
-b: 隻生成索引檔案,不進入cscope的界面
-q: 生成cscope.in.out和cscope.po.out檔案,加快cscope的索引速度
然後在vim中執行<code>:cs add cscope.out</code>,添加資料庫。
接下來就可以使用<code>:cs find x var</code>進行查找。(x代表查詢選項,var表示要查找的函數或變量名)
cscope支援8種查詢方式
s: 查找c語言符号,即查找函數名、宏、枚舉值等出現的地方
g: 查找函數、宏、枚舉等定義的位置,類似ctags所提供的功能
d: 查找本函數調用的函數
c: 查找調用本函數的函數
t: 查找指定的字元串
e: 查找egrep模式,相當于egrep功能,但查找速度快多了
f: 查找并打開檔案,類似vim的find功能
i: 查找包含本檔案的檔案
例如,我們想在vim 7.0的源代碼中查找調用do_cscope()函數的函數,我們可以輸入:”:cs find c do_cscope“,回車後發現沒有找到比對的功能,可能并沒有函數調用do_cscope()。我們再輸入”:cs find s do_cscope“,查找這個c符号出現的位置,現在vim列出了這個符号出現的所有位置。
每次都有輸入<code>cs find</code>來查找資料是不是有點麻煩,有沒有更友善的方法呢。當然有,vim的神奇之處在其可定制性。提供一份cscope的配置,将其放在.vimrc中即可。
<code>"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""</code>
<code>" cscope setting</code>
<code>if has("cscope")</code>
<code>set csprg=/usr/bin/cscope</code>
<code>set csto=1</code>
<code>set cst</code>
<code>set nocsverb</code>
<code>" add any database in current directory</code>
<code>if filereadable("cscope.out")</code>
<code>cs add cscope.out</code>
<code>endif</code>
<code>set csverb</code>
<code></code>
<code>nmap <c-@>s :cs find s <c-r>=expand("<cword>")<cr><cr></code>
<code>nmap <c-@>g :cs find g <c-r>=expand("<cword>")<cr><cr></code>
<code>nmap <c-@>c :cs find c <c-r>=expand("<cword>")<cr><cr></code>
<code>nmap <c-@>t :cs find t <c-r>=expand("<cword>")<cr><cr></code>
<code>nmap <c-@>e :cs find e <c-r>=expand("<cword>")<cr><cr></code>
<code>nmap <c-@>f :cs find f <c-r>=expand("<cfile>")<cr><cr></code>
<code>nmap <c-@>i :cs find i ^<c-r>=expand("<cfile>")<cr>$<cr></code>
<code>nmap <c-@>d :cs find d <c-r>=expand("<cword>")<cr><cr></code>
上面的配置即把<code>ctrl + @</code>作為<code>:cs find</code>的快捷鍵,也就是說要查找某個函數名,隻需要把光标放在函數名上,按下<code>ctrl + @ + s</code>即可,簡直不能更友善。而且你可以自己修改配置,映射到自己覺得舒服的快捷鍵上。
上面我們講的是用vim來檢視源代碼,但是面對幾十萬代碼的時候,想要看清楚各個結構體之間的關系就不是vim能夠做到的了。這時候我們就需要doxygen來幫手了。
doxygen is the de facto standard tool for generating documentation from annotated c++ sources, but it also supports other popular programming languages such as c, objective-c, c#, php, java, python, idl (corba, microsoft, and uno/openoffice flavors), fortran, vhdl, tcl, and to some extent d.
doxygen是一個根據源代碼生成文檔的工具,這貨雖然主要是給c++用的,但是它也對其他語言有支援。
下面介紹一下doxygen的使用方法。
首先,在源代碼根目錄執行<code>doxygen -g</code>,然後在根目錄就會突然冒出一個名為doxyfile的檔案,這個檔案就是doxygen生成文檔的配置檔案了。
那麼,重點來了,怎麼配置這個檔案,預設的配置是根據代碼生成各個結構體的成員資料,然後生成html和latex兩個檔案夾,分别是網頁和latex文檔。
當然了,如果這篇文章唯一給出的建議就是看文檔,那這篇文章有什麼意義呢。大家都知道看文檔可以解決問題,但是時間成本太高,而且是英文的。寫這篇文章的目的是分享自己學習得到的經驗,讓大家少走彎路,如果不能解決你的問題,隻能去看文檔了。
接下來我根據我自己看文檔用到的配置跟大家解釋一下。
首先,doxygen裡面的配置可謂又臭又長,你絕對不會有讀完它的欲望。是以我給出幾個關鍵的配置項,到時候搜尋它修改即可
這是針對各種語言優化輸出的選項,預設都是no,因為它不清楚你用的是什麼語言(話說看一下字尾不就知道了嗎…)
<code>optimize_output_for_c</code>
<code>optimize_output_java</code>
<code>optimize_for_fortran</code>
<code>optimize_output_vhdl</code>
這個是生成文檔的類型的選項,預設生成html和latex,共支援六種類型的文檔,每種類型的生成配置也是很多,具體根據需要配置
<code>generate_html</code>
<code>generate_latex</code>
<code>generate_rtf</code>
<code>generate_xml</code>
<code>generate_docbook</code>
<code>generate_man</code>
關于生成圖像的選項。doxygen使用dot這個工具來繪圖,是以要先執行<code>sudo apt-get install graphviz</code>安裝dot。在設定好這個繪圖選項之後,doxygen就會生成各個結構體的關系,對于類會生成函數調用關系(我沒試過,因為隻試過c的)。
<code>have_dot (一定要置為yes,後面的選項都依賴這個)</code>
<code>dot_num_threads (使用dot繪圖的線程數量,越多越快,我一般是設定跟cpu的核數一樣)</code>
給一個結構體關系圖,就是doxygen生成的。
[machine_class]
最後一步,在源碼根目錄執行<code>doxygen</code>,它會自動找到doxygen配置,根據配置生成文檔。
最後一個工具,大名鼎鼎的gdb。分析源碼執行流程的最好方式的是運作它,然後一步步執行。用來觀察它最好的工具當然是gdb了(針對c/c++)。
以上就是我在閱讀源碼的時候使用的linux工具,三劍客vim+ctags+cscope,兩闆斧doxygen gdb,足以馳騁源代碼的江湖。
以上工具,vim和gdb是最難學的,學習曲線很陡峭。但是學好之後,就能守得雲開見月明。
本文來自雲栖社群合作夥伴“linux中國”,原文釋出日期:2015-08-26