原始碼閱讀環境OpenGrok搭建
工欲善其事,必先利其器。
導語
閱讀原始碼最常見操作的就是在函式/方法的呼叫與定義之間跳轉,對於只有大部分原始碼來說,都可以通過ctags+vim獲得比較好的體驗,但對於Android原始碼這樣10G多的大型專案,這種方法就捉襟見肘了,更不必說對高度定製化的搜尋需求(如查詢某個檔案的某個方法)的支援。
OpenGrok其實就是一個搜尋引擎,只不過不同於Google、Baidu面向的是網頁,OpenGrok面向的是原始碼,通過建立索引,OpenGrok可以幫助我們更好地在浩如煙海的原始碼裡找到自己需要的那部分。
環境搭建
環境搭建的繁瑣程度和最終的便利性成反比,把原始碼解壓出來,隨便裝一個文字編輯器就可以開始閱讀原始碼了,但是如果你真的這樣做就會發現即使查詢某個函式/方法的宣告都極其耗時,所以希望讀者接下來可以保持耐心,因為環境搭建對於原始碼閱讀來說是一件一勞永逸的事情。
對於自學能力強者,建議直接看官方文件: ofollow,noindex">How to setup OpenGrok · oracle/opengrok Wiki
網頁瀏覽器+Servlet
什麼要網頁瀏覽器?因為OpenGrok本質是一個建立和處理索引的工具,就像ctags一樣,我們一般用的編輯器Vim其實充當了一個顯示程式碼的前端的作用,這個裡的網頁瀏覽器其實功能就和Vim類似,用來顯示程式碼。Vim能夠直接解析ctags工具生成的tags檔案,但網頁瀏覽器卻不能,所以需要一個Servlet(伺服器端),用來處理查詢方法、跳轉到方法宣告之類的操作所產生的請求,這裡我們選擇tomcat,版本要求8+。安裝過程如下:
sudo apt-get install tomcat8 sudo /etc/init.d/tomcat8 restart
開啟 http://localhost:8080/ 看到類似下面的網頁說明成功了:

image
最後下載 OpenGrok ,並把 source.war
這個檔案放在Tomcat的webapp目錄下:
sudo cp ~/下載/opengrok-1.1-rc41/lib/source.war /var/lib/tomcat8/webapps
此時 http://localhost:8080/source/ 應該就能訪問了,但是可能會報一些錯誤,只要不是404就不要慌,繼續配置。
JDK1.8+
官方明確要求JDK1.8及以上版本,如果版本低會報
An error occurred at line: 55 in the jsp file: /menu.jspf '<>' operator is not allowed for source level below 1.7
之類的錯誤,如何安裝JDK的教程很多,不做贅述。
通過 java -version
和 javac -version
可以檢視版本。
ctags
必須是 universal-ctags
,否則後面建立索引的時候會報錯:
嚴重: Exception running indexer org.opengrok.indexer.index.IndexerException: Didn't find Universal Ctags at org.opengrok.indexer.index.Indexer.prepareIndexer(Indexer.java:888) at org.opengrok.indexer.index.Indexer.main(Indexer.java:298)
一般通過 apt-get
安裝的都是 exuberant-ctags
,要注意:
sudo apt-get install tags[TAB] exuberant-ctagsgeany-plugin-ctagslibparse-exuberantctags-perl
可以直接下載 universal-ctags
的原始碼來編譯安裝:
# prepare sudo apt-get remove ctags sudo apt-get autoremove sudo apt-get install autoconf sudo apt-get install automake git clone https://github.com/universal-ctags/ctags.git cd ctags ./autogen.sh ./configure make sudo make install
其他
足夠的硬碟空間。
匯入原始碼
管理原始碼
OpenGrok會通過一個目錄存放所有需要被索引的工程,通過一個目錄存放索引,對於需要建立索引的原始碼,為了不影響其他操作,我們可以建立一個目錄 opengrok-workspace
(名字自定義,下同),將原始碼放在 project
目錄下,索引放在 data
目錄下。但這樣直接移動原始碼實在不夠優雅,其實 project
目錄存在的意義是讓OpenGrok知道哪些工程需要被索引,所以我們只需建立一個軟連結(Windows下的快捷方式)就行了,這裡我為Android原始碼、Vim原始碼和Git原始碼建立了軟連結,表示我需要索引這三個工程:
cd ~/opengrok-workspace/project ln -s ~/SourceCode/Android_6.0/mydroid/ Android6.0 ln -s ~/SourceCode/git/ git ln -s ~/SourceCode/vim/ vim
效果如下:
~/opengrok-workspace/project $ ls Android6.0gitvim
這樣我們不想索引某個專案只需要移除他的軟連結(幾kb)就行了,而不必移動專案本身(動輒幾G)。
引數配置
強烈建議通過 java -jar ~/Install/opengrok-1.1-rc41/lib/opengrok.jar -h
檢視每一個引數的意義,比如我最終的命令是下面這樣:
java -jar ~/Install/opengrok-1.1-rc41/lib/opengrok.jar -P -S -v -s ~/opengrok-workspace/project -d ~/opengrok-workspace/data -I *.java -I *.c -I *.h -I *.cpp -W ~/opengrok-workspace/configuration.xml
其中 -s
表明專案地址, -d
表明索引輸出地址, -W
表明配置輸出地址,都是必須的。對於Git和Vim不要 -I
引數可能都沒有問題,但對於Android原始碼,如果不要這個引數產生的索引就會不可用,因為 .jar
、 .so
等檔案都無法建立索引,所以這裡我指定了只對Java和C、C++相關的檔案建立索引,不僅建立速度更快,佔用空間也更小。
Tomcat配置
最後,去 /var/lib/tomcat8/webapps/source/WEB-INF
目錄配置 CONFIGURATION
引數,讓伺服器端知道索引在哪:
...... <context-param> <description>Full path to the configuration file where OpenGrok can read its configuration</description> <param-name>CONFIGURATION</param-name> <param-value>/home/zhaoyu/opengrok-workspace/configuration.xml</param-value> </context-param> ......
按照上面的命令重啟Tomcat伺服器端使新的配置生效,最後大功告成:

image
總結
本文只是介紹了環境的基本搭建流程,OpenGrok支援高度定製,這裡只使用了最基本的引數。此外,前端和伺服器端也可以根據自己的喜好定製,例如 asenac/vim-opengrok 和 jdevera/vim-opengrok-search 都在嘗試把Vim作為瀏覽程式碼的前端,當然在Chrome裡面裝個 vimium
也能獲得類似的體驗。