推荐一下阅读大项目神器OpenGrok
前言
当进入到一个陌生的大型项目, 又或是为了疑难杂症要去阅读开源项目, 比如AOSP、OpenJDK 或 Linux Kernel这种大型开源项目, 会发现这些项目, 不仅仅代码量大得惊人(AOSP clone下来就有50G了), 还常常混合多种语言. 如何快速准确的查找代码调用关系、理清逻辑, 是非常大的挑战. 能胜任这种场景的工具, 可能只有Source Insight.
因为Source Insight, 可以提供:
- 准确完善的代码解析和分析查找功能
- 极高的性能
- 极低的系统资源占用
可惜SI只在Win平台上面有. 在Mac上, 用Wine或者用虚拟机来启动它,又慢又不稳定.
1 常见编辑器能替代SI吗?
1.1 IDE
IntelliJ 或Eclipse等IDE, 主要还是用来写代码的, 这会导致IDE, 不适应我们阅读源码的场景.
比如AOSP项目, 是由接近300个子项目组成, 这些子项目中, 像 chrominum 本身就是一个复杂项目, 有着自己的代码结构和编译配置. IDE大多针对某种语言的垂直场景, 适应不了这么复杂的场景.
如果不把项目build success, 并且把依赖按照IDE的方式配置好. 就得面对一堆堆的红色报错, 和部分功能不可用的问题. 但是, AOSP之类的源码, build非常麻烦, 编译成本非常高. 一方面是编译时间, 一方面是会占用海量的硬盘空间. 最新AOSP, 不开启CCACHE, 编译后, 会占100G左右空间. 如果开启默认建议的20+G 的CCACHE, 会占用更多硬盘空间.
还有就是, IDE大多针对中小型项目的开发, 从IDE设计者的角度, 是用空间换时间, 所以消耗的资源, 是与项目大小强相关的, 项目越大消耗的资源就越大, load 大项目的IDEA, 简直卡得不要不要的
1.2 Vim + vim-awesome插件包
不管什么编辑器, 我都会安装Vim plugin, 所以我也非常喜欢独立的, 通过vim-awesome配置的Vim环境。当然, 少不了会安装ctags+cscope+NERDTree 等等插件包。
不过, 说实话, 这种环境, 偶尔秀一下还可以, 真要在一个陌生项目中, 频繁的跳转和查找调用关系,手很容易抽筋的. 这种环境更适合阅读和开发有一定熟悉度的代码,而不适合相对陌生, 需要频繁查找和跳转的大型项目。
1.3 Sublime || Atom || VS Code
另一种常见环境,是基于Sublime+ctags+cscope。
Sublime 有一个至今未解决的, 具有普遍性的bug Sublime keeps indexing and heating up my computer. 这个bug, 在open 文件多的大型项目后, 即使用户什么都不做, 它都会不停的index, 导致笔记本严重发热, 电量快速下降.
另外, Sublime已经逐渐被一些插件开发者抛弃, 类似material-theme的 Deprecation note
1.4 ctags & cscope的问题
无论是把Sublime换成Atom 或 VS Code, 又或是Vim环境, 都会遇到下面这两个问题:
第一, ctags & cscope都不支持增量索引, 每次更新代码后, 都需要对整个项目重建索引, 时间成本非常高
第二, ctags默认配置对包含java c++等多语言的项目支持比较差. 要确保准确解析包含多语言的项目, 需要配置下面这种, 天书一样的参数.
2. 体验OpenGrok
一个偶然的机会,我找到了Sun的OpenGrok, OpenGrok的界面, 浓浓的历史味道, 让人觉得这货不简单. 随着长时间的体验, 我更认定它就是Source Insight在Mac平台的替代品。
OpenGrok is a source code search and cross reference engine. It helps programmers to search, cross-reference and navigate source code trees
2.1 使用OpenGrok的案例
非常多的公益大型源码阅读网站, 是基于OpenGrok部署的, 可以体验
- http://opengrok.libreoffice.org/ — LibreOffice
- http://androidxref.com/ — Android
- http://src.illumos.org/source/ — illumos, FreeBSD, Linux
3 OpenGrok的功能介绍
3.1 Analysis功能
OpenGrok有强大的Analysis功能
Analysis支持主流的版本控制系统, 如CVS、Git、Mercurial等, 并能对SCM的记录进行分析, 然后提供快速查找history和展示Annotations的功能.
Analysis还内置了很多分析引擎, 比如C/C++, 比如Shell, 比如XML等等, 在index的过程中, 每个文件, 会分配到这些引擎上解析, 为源码的变量/对象、结构体/类、函数/接口、宏等生成可供快速搜索的索引文件
3.2 搜索功能
与IDE的侧边栏文件树不同, OpenGrok提供的是搜索直达. 这也非常符合我们看源码的场景, 源码非常庞杂, 我们常常是带着问题, 以某个函数或接口切入, 去摸索的.
OpenGrok的搜索功能是非常强大的:
- 对 full text, definitions, symbols, path 或 revision history等进行搜索
- 限制在某个子目录里面搜索
- 支持类似Google Search的搜索语法, 比如 path:Makefile defs:target
- 支持根据修改时间段进行搜索
- 支持模糊匹配搜索, * 匹配多个字符, ? 匹配单个字符
- 支持正则 path:/ma[a-zA-Z]*/
- 支持多条件 -“/usr/bin/perl” +”/bin/perl”
- 极速. 得益于index和Apache Lucene, 可以在几十万文件中, 进行多条件搜索, 只需要几毫秒
详细的搜索帮助, 可以通过点击搜索框底部的help按钮进行学习, 会路由到一个help.jsp页面, 如 https://opengrok.housegordon.com/source/help.jsp
一个搜索到例子如下:
3.3 主界面使用
3.3.1 Navigate
点击导航栏上面的 Navigate# , 可以切换右侧方法列表展示
3.3.2 intelligence window
先把鼠标箭头, 移动到目标方法上面, 然后按一下键盘上的数字 1, 可以呼出 intelligence window
这里面有
- Highlight / UnHighlight
- Search definitions
- Search references
等等辅助理解代码关系的功能
3.3.3 highlight
先把鼠标箭头, 移动到目标方法上面, 然后按一下键盘上的数字 2, 可以快速切换Highlight / UnHighlight
这个功能, 在理解某个方法的时候非常有用.
4 安装本地OpenGrok
受制于网络情况和GFW, 本地会更加实用. 官方安装流程 分为几大步骤:
- 安装tomcat
- 安装ctags
- 安装opengrok
- 部署opengrok到tomcat
- 配置参数
- 索引代码, 开始使用
4.1 我推荐的安装版本
我之前有搭建了最新版本的OpenGrok + Universal Ctags, 但是我在索引Android源码的时候, 遇到了很多问题, 比如说android.view.View这种复杂一点的类, 会解析不完整. 但是同样基于OpenGrok的 AndroidXRef 就可以完美解析
我后来有去咨询OpenGrok, 得到的回复如下:
For reference, androidxref seems to be using 0.11.1
然后, 我测试了, 从0.11.1到1.0等多个版本, 发现, 只要是可以使用Exuberant Ctags, 就没有问题. 1.0以后逐渐默认切到了Universal ctags, 但还不够成熟, 在大型项目的兼容性上, 还不是特别稳定
最终, 我在Mac下使用了如下版本进行搭建, 可以完美解析Android 源码和其他各个大型项目源码:
- JDK 8
- tomcat 8.5.31
- OpenGrok 1.0 tar
- Exuberant Ctags 5.8
4.2 具体安装流程
4.2.1 安装Tomcat
我们下载tomcat 8.5.31, 解压到目录, 比如~/env/tomcat, 然后将该目录添加到环境变量
export OPENGROK_TOMCAT_BASE=~/env/tomcat
4.2.2 安装ctags
使用 brew install ctags 安装ctags, 并确保 ctags —version 输出的, 是Exuberant Ctags
4.2.3 安装opengrok
下载OpenGrok 1.0 tar , 并解压到目录,比如 ~/opengrok, 然后将该目录添加到环境变量:
1 | export OPENGROK_INSTANCE_BASE=~/opengrok |
4.2.4 部署opengrok到tomcat
在命令行进入刚才的~/opengrok/bin目录, 执行1
./OpenGrok deploy
可以看到如下输出
Loading the default instance configuration …
Installing ./../lib/source.war to /Users/xiaoxinpeng/env/tomcat/webapps …
Start your application server (Tomcat), if it is not already
running, or wait until it loads the just installed web application.
OpenGrok should be available on
where HOST and PORT are configured in Tomcat.
4.2.5 配置参数
首先是对tomcat的配置, 在刚才的安装目录 ~/env/tomcat 下, 我们对conf/server.xml文件进行修改, 该文件70行附近, 有对Connector的配置, 我们加入maxHttpHeaderSize=”65536”,如下
1 | <Connector port="8080" protocol="HTTP/1.1" |
4.2.6 提升index速度
然后是对opengrok索引速度的修改:
将下面几行, 加入环境变量, 即可极大加速opengrok的index速度:
1 | export JAVA_OPTS="-Xmx8192m -server" |
4.2.7 index
我们先进入 ~/opengrok/bin目录
再执行 ./OpenGrok index
等整个索引结束以后, 在浏览器, 打开 http://127.0.0.1:8080/source/ 就可以使用了