RTFSC 是程式設計師打怪升級路上避不開的功課,那營造一個舒適的環境來提升上課的體驗就很有必要了。
比如閱讀 AOSP 這種大型原始碼,用什麼姿勢來閱讀才能絲般順滑,讓 F**king Source Code 也變得不那麼可惡呢?
工具的選擇
閱讀原始碼的工具我嘗試過以下幾類:
IDE
在看特定型別專案時這是我的首選。比如它原本就是一個 Visual Studio 工程,那當然用 Visual Studio 來開啟閱讀,看 Android App 或者 Library 原始碼當然用 Android Studio 體驗更好。
編輯器配合外掛
比如 Vim + Ctags + Cscope,再配合檔案模糊查詢外掛 LeaderF 和神器 YouCompleteMe,在原始碼規模不大時很方便,開啟也輕快,閱讀一些小專案時我還是樂意使用它們。
專門的原始碼閱讀工具
在針對特大型原始碼時,比如 AOSP 和 Chromium,使用上述兩種方案可能會感覺乏力,這時候就需要祭出專門的原始碼閱讀工具了。
一類是商業軟體,比如 Windows 下有著名的 Source Insight,跨平臺的有 Understand,功能都很強大,都是不錯的選擇。當然它們都價格不菲。
而我這裡要講的主角 OpenGrok 屬於另一類,免費,開源,執行流暢,功能也毫不遜色。
如果你還在尋覓適合你自己的解決方案,大可以花一點時間將以上幾種都嘗試一遍,哪個稱手用哪個,也可以像我一樣,針對不同的專案使用不同的工具。想直觀瞭解 OpenGrok 的同學可以直接先看看一些使用 OpenGrok 的線上原始碼檢視網站,看看它能否滿足你的需求,其中的一些列在 OpenGrok installations。
OpenGrok 特性
譯自官方 Wiki。
OpenGrok 提供如下特性:
快速搜尋程式碼的引擎
搜尋全文、定義、符號、檔案路徑和修改歷史
搜尋任意指定子目錄(分層搜尋)
增量更新索引檔案
支援類似 Google 的查詢語法,比如
path:Makefile defs:target
搜尋日期範圍內修改的檔案
支援使用萬用字元搜尋,如
*
表示多個字元,?
表示單個字元在搜尋結果中展示匹配行
一個 Web 只讀版的版本歷史檢視介面
檔案的修改日誌
檔案在兩個版本間的 diff
資料夾的歷史記錄
帶語法高亮的交叉引用顯示,可以使用 CSS 自定義樣式
可以開發外掛支援新的語言和版本控制系統
已經支援的語言: Supported Languages and Formats
已經支援的版本控制系統:Supported Revision Control Systems
配置 OpenGrok
截圖
按慣例先上圖吧,萬一你一眼就發現不是你的菜呢(截圖來自官網)。
搜尋功能和原始碼樹:
程式碼導航和版本歷史記錄:
安裝和配置
如下以 Windows 下為例,Mac OS X 與 Linux 下與此類似,很多步驟能使用 brew 或者 apt-get 會更方便。
安裝 JDK,並配置 JAVA_HOME 或者 JRE_HOME 環境變數為安裝目錄。
下載 Tomcat,解壓到一個目錄,如 D:\Programs\apache-tomcat-8.5.8,並將此目錄新增為 CATALINA_HOME 環境變數。
下載 Universal Ctags for Windows,將 ctags.exe 檔案所在目錄新增到 PATH 環境變數。
下載 OpenGrok 的最新包,比如 opengrok-0.13-rc4.zip,解壓到一個目錄,如 D:\Programs\opengrok-0.13-rc4。
配置 data root。
data root 用於放置生成的索引檔案和配置資訊,比如我在 OpenGrok 目錄下建立了一個 data 目錄用作 data root,即 D:\Programs\opengrok-0.13-rc4\data。
將 OpenGrok 的 lib 目錄裡的 source.war 解壓到 D:\Programs\apache-tomcat-8.5.8\webapps\source,配置 WEB-INF\web.xml 檔案的 CONFIGURATION 為上一步生成的 data 目錄下的 configureation.xml,比如我的配置:
<display-name>OpenGrok</display-name> <description>A wicked fast source browser</description> <context-param> <description>Full path to the configuration file where OpenGrok can read its configuration</description> <param-name>CONFIGURATION</param-name> <param-value>D:/Programs/opengrok-0.13-rc4/data/configuration.xml</param-value> </context-param>複製程式碼
配置 source root。
可以讓 OpenGrok 認為 source root 下的每個子資料夾是一個專案,所以我們利用這個特性來配置和閱讀多個專案原始碼就好了。
我的做法是在 OpenGrok 下建立了一個子目錄 D:\Programs\opengrok-0.13-rc4\projects,然後將需要閱讀的原始碼使用符號連結的方式連結到這個目錄裡:
cd /d D:\Programs\opengrok-0.13-rc4\projects mklink /J android D:\sources\android_5.1 mklink /J openjdk7 D:\sources\openjdk7複製程式碼
這樣就有一個叫 android 的工程,它實際對應 D:\sources\android_5.1 下的原始碼,一個叫 openjdk7 的工程,它實際對應 D:\sources\openjdk7 下的原始碼。
建立索引。
使用 opengrok.jar 呼叫 ctags 來為原始碼建立索引。命令列:
java -jar /path/to/opengrok.jar -P -S -v -s /path/to/source/root -d /path/to/data/root -W /path/to/configuration.xml複製程式碼
-P
表示為 source root 目錄下的每個一級子目錄生成一個工程。-S
表示搜尋並新增 "external" source repositories。-v
表示列印操作的進度資訊。-s
表示指定 source root。-d
表示指定 data root。-W
表示指定將配置寫到該檔案。還有更多配置選項可以使用
java -jar /path/to/opengrok.jar
檢視。比如我使用的完整命令列:
java -jar D:\Programs\opengrok-0.13-rc4\lib\opengrok.jar -P -S -v -s D:\Programs\opengrok-0.13-rc4\projects -d D:\Programs\opengrok-0.13-rc4\data -W D:\Programs\opengrok-0.13-rc4\data\configuration.xml複製程式碼
每次需要建立或更新索引的時候敲這麼長一個命令當然很不爽,使用 doskey 或者 Cmder 裡的 alias 命令將其 alias 為 opengrok-index 命令會省力不少,再不濟把這命令存成個 bat 檔案也行啊。
為大型原始碼建立索引可能需要漫長的時間,這時候可以去幹點別的事了。
啟動 Tomcat,愉快地 RTFSC。
D:\Programs\apache-tomcat-8.5.8\bin\catalina.bat start複製程式碼
用你最愛的瀏覽器開啟 http://localhost:8080/source/,然後就能愉快地跟 OpenGrok 玩耍了。
當新新增了專案,或者現有專案有原始碼更新時,再次執行上一步的命令,就能增量更新索引了。
配置多專案
我曾經為如何在 OpenGrok 裡配置多專案苦惱了好久——一開始我是把 Android 原始碼的根目錄當作 source root 的,可想而知 OpenGrok 把 Android 分成了好多個子專案,而這時我也沒法再新增新的工程了。
後來才發現建一個專用的 source root,然後把各種專案原始碼根目錄軟連結過來,讓 OpenGrok 為 source root 下的每個 symbol 一級子目錄建立一個專案才是正確的使用方法。
Windows 下建立軟連結的方法是使用 mklink /J android D:\sources\android_5.1
,Mac OS X 和 Linux 下可以使用 ln -s /path/to/source project_name
。
折騰狂魔
在 Vim 裡使用
沒錯,還有人做了支援在 Vim 裡使用 OpenGrok 的外掛,如果你是 Vim 控+折騰狂魔,可以一試,這裡僅給出外掛地址:
反正像我這種智商是折騰不動了,就安心在瀏覽器裡用了。
在原始碼裡做筆記
配合 Chrome 外掛 Diigo,還能給原始碼加標籤,寫註釋等等。
後話
古人教會了我們工欲善其事,必先利其器的智慧,但我們也不能沉迷和徘徊於各種利器之間,選擇一樣自己感覺最稱手的工具,把它用熟練,少再在這上面花時間折騰,畢竟把有限的生命投入到無限的 RTFSC 才是正道不是麼。