当前位置: 首页 > 工具软件 > Code Browser > 使用案例 >

使用woboq_codebrowser阅读C/C++源码

齐航
2023-12-01

为什么写本文

学习工作中阅读学习C/C++项目代码,在Windows下大多数人使用Source Insight这个工具,而在Linux下我一般喜欢vim配合ctags来使用。不过发现它们有一个共同的问题,就是对C++中的符号解析得不够精细,例如不支持从运算符重载函数声明处跳转到其定义处。因此通过Google搜索希望有更好的工具来替代,这才发现了本文将向大家推荐的工具,它就是woboq_codebrowser

网站https://woboq.com向我们展示了利用woboq_codebrowser解析的几个大型C/C++项目,包括 Qt | GLibc | LLVM | Boost | GCC | Linux。通过实际体验,发现woboq_codebrowser的确强大,尤其对C++的符号解析得更加精细。

本文首先会简单介绍下woboq_codebrowser的工作原理,然后带领大家一步步安装woboq_codebrowser,最后通过实际使用它来解析一个C++项目,完整地向大家展示woboq_codebrowser的用法。

woboq_codebrowser当然有它的缺点,那就是不支持代码编辑。


woboq_codebrowser工作原理简介

首先大致了解下woboq_codebrowser的工作原理吧。

woboq_codebrowser是基于LLVM/Clang实现的一个命令行工具。它通过深度解析C/C++源码生成最终我们需要的静态HTML文件。woboq_codebrowser包含codebrowser_generatorcodebrowser_indexgenerator两个子命令。生成HTML文件到最终可以通过浏览器阅读代码,整体分三个步骤:

  1. 先通过codebrowser_generator解析.h和.cpp生成对应的 .h.html.cpp.html
  2. 然后通过codebrowser_indexgenerator为所有目录生成 index.html
  3. 最后我们可以把这些HTML文件拷贝到某个Web服务器上,就可以在浏览器里愉快地浏览C/C++项目的源码了。

woboq_codebrowser的编译和安装

本文演示在Ubuntu 18.04 LTS上通过源码编译安装woboq_codebrowser的完整步骤。

1. 获取源码

通过git把woboq_codebrowser源码clone到本地。

$ git clone https://github.com/woboq/woboq_codebrowser

其中 generatorindexgenerator 目录里的代码分别是命令codebrowser_generatorcodebrowser_indexgenerator的源码。

特别的,data 目录里的文件并不是源码,而是一些网页数据,你可以看到一些Javascript脚本文件,CSS文件以及很多png格式的图片。这些网页数据会在make install时拷贝到系统相应的位置,例如woboq_codebrowser默认的 install prefix/usr/local,那么codebrowser_generatorcodebrowser_indexgenerator最终会安装到 /usr/local/bin 目录里,data 目录会被拷贝到 /usr/local/share/woboq 目录下。

另外一点需要注意:通过阅读README文件,了解到在Ubuntu系统上LLVM的版本需要大于等于7版本,否则会报找不到ClangConfig.cmake文件的错误。并且通过issue#74了解到这其实不是LLVM的bug,而是debian包管理出现的一个bug(Ubuntu包管理是基于debian包管理的)。因此我们在下一步编译时可以指定特定版本的编译器来避免这个坑。

2. 编译安装

woboq_codebrowser需要使用cmake来构建,因此需要确保系统已经安装好了cmake。
我们可以告诉cmake是用g++编译还是clang++编译。

使用g++编译

命令如下(我的g++版本是(Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0):

# gcc
cmake . -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_CXX_COMPILER=g++ \
        -DLLVM_DIR="/usr/lib/llvm-7/cmake"
make && sudo make install

注意到了吗? 我通过指定LLVM_DIR为LLVM-7的路径,这就避免了刚刚提到的issue#74问题。当然了,也可以指定更高版本的LLVM路径,都是可以的。

使用clang++编译

命令如下:

$ cmake . -DCMAKE_BUILD_TYPE=Release \
		-DCMAKE_CXX_COMPILER=clang++ \
		-DLLVM_DIR="/usr/lib/llvm-7/cmake"
$ make && sudo make install

至此,不出意外的话,woboq_codebrowser这就编译安装成功了。


woboq_codebrowser的使用

这里我通过LIEF这个项目来做演示,详细展示使用woboq_codebrowser的具体步骤。

1. 获取compile_commands.json文件

compile_commands.json文件是一种特定格式的 compilation database 文件,而所谓 compilation database 其实很简单,它里面记录的是每一个源码文件在编译时详细的信息(包括文件路径,文件名,编译选项等等)。而compile_commands.json文件是 LibTooling 需要的以JSON格式呈现的 compilation database 文件,以下截取的是compile_commands.json中的一个entry:

[
...
    {
        "arguments": [
            "c++",
            "-c",
            "-g",
            "-O2",
            "-Werror",
            "-std=c++0x",
            "-Wall",
            "-fPIC",
            "-o",
            "attrs.o",
            "attrs.cc"
        ],
        "directory": "/home/astrol/libelfin/dwarf",
        "file": "attrs.cc"
    },
...
]

前面说过woboq_codebrowser是基于LLVM/Clang实现的工具,那么自然也是基于compile_commands.json来分析源码关系的。
就是说,要想使用woboq_codebrowser,必须首先生成compile_commands.json文件。如果项目是由cmake构建的,那么恭喜你,只需加上-DCMAKE_EXPORT_COMPILE_COMMANDS=ON即可。如果是传统的make build system也不要担心,Bearcompdb工具可以帮我们生成compile_commands.json文件。特别的,Android从7.0版本之后,构建系统换做Soong之后也提供了对应的方法

2. 使用codebrower_generator生成HTML

先来简单了解下woboq_codebrowser常用参数的意义如下,更多的参数可以通过woboq_codebrowser --help去查看。

  1. -a process all files from the compile_commands.json. If this argument is not passed, the list of files to process need to be passed
    告诉woboq_codebrowser处理compile_commands.json中记录的每一个文件。
  2. -o=<output path> Output directory where the generated files will be put
    告诉woboq_codebrowser生成的HTML存放在哪个目录。
  3. -b=<compile_commands.json> Path to the compilation database (compile_commands.json) If this argument is not passed, the compilation arguments can be passed on the command line after ‘–’
    告诉woboq_codebrowser在哪个路径可以找到compile_commands.json
  4. -p=<<project>:<path>[:<revision>]> Project specification: The name of the project, the absolute path of the source code, and the revision separated by colons. Example: -p projectname:/path/to/source/code:0.3beta
    告诉woboq_codebrowser一些当前需要处理的project的信息,包括project名称,路径以及版本信息。

3. 使用codebrowser_indexgenerator为每个目录生成index.html

命令codebrowser_indexgenerator的使用比codebrower_generator要简单很多,后头直接指定一个路径就好。
现在以LIEF为列(我当前处于LIEF源码目录内,并成功生成了compile_commands.json):

#/usr/bin/env bash
DATA_DIRECTORY=/usr/local/share/woboq/data
OUTPUT_DIRECTORY=/tmp/lief
if [ -d ${OUTPUT_DIRECTORY} ]; then
    rm -rf ${OUTPUT_DIRECTORY}/*
else
    mkdir -p ${OUTPUT_DIRECTORY}
fi
BUILD_DIRECTORY=$PWD
SOURCE_DIRECTORY=$PWD
VERSION=`git describe --always --tags`

codebrowser_generator -color -a -b $BUILD_DIRECTORY -o $OUTPUT_DIRECTORY \
        -p LEIF:$SOURCE_DIRECTORY:$VERSION -d ${DATA_DIRECTORY}
codebrowser_indexgenerator $OUTPUT_DIRECTORY
cp -rfd $DATA_DIRECTORY $OUTPUT_DIRECTORY

4. 将生成的所有文件拷贝到web服务器

这里推荐大家使用nginx在本地搭建一个web服务器使用,可以参考《搭建Nginx本地web开发服务》


参考链接

《Compilation databases for Clang-based tools》
《Compilation database》
《JSON Compilation Database Format Specification》
《Compilation database》

 类似资料: