看源代碼是一個程序員必須經歷的事情,也是可以提升能力的一個捷徑。個人認為: 要完全掌握一個軟件的方法只有閱讀源碼。
在Windows下有sourceinsight這個源碼閱讀軟件(雖然我沒用過,但是網上評價還不錯),由於我是個Linuxer,並不喜歡用Windows,所以自然是選擇在Linux下閱讀源碼的工具了。
下面我將逐一介紹在Linux下閱讀源碼的工具。
源碼閱讀三劍客:vim配合ctags和cscope,足以在源代碼裡面自由翱翔,在函數和變量間自由跳轉。
sudo apt-get install vim ctags cscope
vim的使用就略過了,網上資料很多,不是一篇文章能說完的,未來我可能會寫一篇vim的使用心得。推薦一篇簡明 Vim 練級攻略,看完就差不多會用了。
ctags的使用很簡單,vim已經內置了對ctags的支持。
首先在源代碼根目錄執行ctags -R
,遞歸的為源碼建立tags,在根目錄會生成一個Tags的文件,存放各種函數和變量的tag,便於跳轉:
Ctrl + ]
即可跳轉到其定義處Ctrl + t
可以回到你跳轉之前的位置對於簡單的代碼,ctags就夠用了,但是對於比較復雜的代碼來說,ctags顯得有點力不從心,於是,下一位劍客就登場了。
vim同樣內置了對cscope的支持。
首先在源代碼根目錄執行cscope -Rbq
,就會生成cscope.out文件(索引數據庫)
然後在vim中執行:cs add cscope.out
,添加數據庫。
接下來就可以使用:cs find x var
進行查找。(x代表查詢選項,var表示要查找的函數或變量名)
cscope支持8種查詢方式
例如,我們想在vim 7.0的源代碼中查找調用do_cscope()函數的函數,我們可以輸入:”:cs find c do_cscope“,回車後發現沒有找到匹配的功能,可能並沒有函數調用do_cscope()。我們再輸入”:cs find s do_cscope“,查找這個C符號出現的位置,現在vim列出了這個符號出現的所有位置。
每次都有輸入cs find
來查找數據是不是有點麻煩,有沒有更方便的方法呢。當然有,vim的神奇之處在其可定制性。提供一份cscope的配置,將其放在.vimrc中即可。
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" cscope setting
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
if has("cscope")
set csprg=/usr/bin/cscope
set csto=1
set cst
set nocsverb
" add any database in current directory
if filereadable("cscope.out")
cs add cscope.out
endif
set csverb
endif
nmap <C-@>s :cs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-@>g :cs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-@>c :cs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-@>t :cs find t <C-R>=expand("<cword>")<CR><CR>
nmap <C-@>e :cs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-@>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
nmap <C-@>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
nmap <C-@>d :cs find d <C-R>=expand("<cword>")<CR><CR>
上面的配置即把Ctrl + @
作為:cs find
的快捷鍵,也就是說要查找某個函數名,只需要把光標放在函數名上,按下Ctrl + @ + s
即可,簡直不能更方便。而且你可以自己修改配置,映射到自己覺得舒服的快捷鍵上。
本著不重復造輪子的原則,我就簡單的寫了cscope的基本用法,其實基本上就夠用了,進階的用法參考這篇文章vi/vim使用進階: 程序員的利器 – cscope。
上面我們講的是用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的使用方法。
首先,在源代碼根目錄執行doxygen -g
,然後在根目錄就會突然冒出一個名為Doxyfile的文件,這個文件就是doxygen生成文檔的配置文件了。
那麼,重點來了,怎麼配置這個文件,默認的配置是根據代碼生成各個結構體的成員數據,然後生成html和latex兩個文件夾,分別是網頁和latex文檔。
說實話,默認生成的文檔並沒有什麼卵用,除了讓你更方便的看到各個結構體的組成成員。我們關心的是各個結構體之間的關系,這是針對C而言的。對與C++和java而言,關心的是類之間的關系。所以,默認的配置肯定是要修改的。至於怎麼改,看官方文檔。
當然了,如果這篇文章唯一給出的建議就是看文檔,那這篇文章有什麼意義呢。大家都知道看文檔可以解決問題,但是時間成本太高,而且是英文的。寫這篇文章的目的是分享自己學習得到的經驗,讓大家少走彎路,如果不能解決你的問題,只能去看文檔了。
接下來我根據我自己看文檔用到的配置跟大家解釋一下。
首先,Doxygen裡面的配置可謂又臭又長,你絕對不會有讀完它的欲望。所以我給出幾個關鍵的配置項,到時候搜索它修改即可
這是針對各種語言優化輸出的選項,默認都是NO,因為它不清楚你用的是什麼語言(話說看一下後綴不就知道了嗎…)
OPTIMIZE_OUTPUT_FOR_C
OPTIMIZE_OUTPUT_JAVA
OPTIMIZE_FOR_FORTRAN
OPTIMIZE_OUTPUT_VHDL
這個是生成文檔的類型的選項,默認生成html和latex,共支持六種類型的文檔,每種類型的生成配置也是很多,具體根據需要配置
GENERATE_HTML
GENERATE_LATEX
GENERATE_RTF
GENERATE_XML
GENERATE_DOCBOOK
GENERATE_MAN
關於生成圖像的選項。doxygen使用dot這個工具來繪圖,所以要先執行sudo apt-get install graphviz
安裝dot。在設置好這個繪圖選項之後,doxygen就會生成各個結構體的關系,對於類會生成函數調用關系(我沒試過,因為只試過C的)。
HAVE_DOT (一定要置為YES,後面的選項都依賴這個)
DOT_NUM_THREADS (使用dot繪圖的線程數量,越多越快,我一般是設置跟cpu的核數一樣)
給一個結構體關系圖,就是doxygen生成的。
[machine_class]
最後一步,在源碼根目錄執行doxygen
,它會自動找到Doxygen配置,根據配置生成文檔。
最後一個工具,大名鼎鼎的gdb。分析源碼執行流程的最好方式的是運行它,然後一步步執行。用來觀察它最好的工具當然是gdb了(針對C/C++)。
gdb的使用我也不打算造輪子,直接參考用GDB調試程序,這篇寫的很好,通俗易懂。
以上就是我在閱讀源碼的時候使用的Linux工具,三劍客vim+ctags+cscope,兩板斧doxygen gdb,足以馳騁源代碼的江湖。
以上工具,vim和gdb是最難學的,學習曲線很陡峭。但是學好之後,就能守得雲開見月明。