Seriously use the strongest C / C ++ indexer "Rtags"

A tag jump that allows you to jump to a function definition or reference with a single key. Nowadays, it is an indispensable function for code reading, but it is possible to do this with "indexers" such as Ctags and GNU GLOBAL (Gtags). In this article, I'll write about how to set up Rtags, a great indexer for C / C ++, and how to work with Vim.

** Benefits of Rtags **

An indexer is a program that parses source code and creates a tag (index) database that records symbol names and positions of functions and variables. Ctags is one of the most widely used indexers today and supports over 40 languages including C, Ruby and Python. However, in C ++, due to the complexity of the grammar, the internal parser cannot handle it sufficiently, and the symbol name may not be recognized correctly. Gtags has a similar problem. That's where Rtags came in recently. Rtags is characterized by using the parsing interface of clang, which is a C / C ++ compiler. Since the compiler parses the source code, mistakes cannot occur and it is very rational.

** Install Rtags **

The installation itself only requires a build and is not particularly difficult.

** Required packages **

In my Ubuntu-14.04, I entered with the following command. If you check the version of libclang with llvm-config, you will find that it is 3.4.

$ sudo apt-get install clang libclang-dev cmake
$ llvm-config --version
3.4

There is no problem as it is, but libclang is recommended to be 3.5 or higher, so it is a good idea to install 3.6.

$ sudo apt-get install libclang-3.6-dev
$ /usr/lib/llvm-3.6/bin/llvm-config --version
3.6

In this case, when you perform cmake later, you need to give LIBCLANG_LLVM_CONFIG_EXECUTABLE the path of 3.6 llvm-config and execute it as shown below. If you forget this, the default 3.4 will be used.

$ LIBCLANG_LLVM_CONFIG_EXECUTABLE=/usr/lib/llvm-3.6/bin/llvm-config cmake ..

** Build **

Clone the repository and update the dependent submodules.

$ git clone https://github.com/Andersbakken/rtags
$ cd rtags
$ git submodule init
$ git submodule update

Generate and build Makefile with cmake. Create a build directory and build out-of-source from there.

$ mkdir build
$ cd build
$ cmake ..
$ make
$ sudo make install

What is an out-of-source build? For those who say, this article is detailed.

** Rtags setup **

When the installation is complete, you should be able to use the commands rc and rdm. Rtags is a client-server type tag system, and the following is a rough flow of indexing.

  1. Start rdm
  2. ** Give the command to compile the indexed source file with rc **
  3. rdm receives the above command from rc and indexes

The most important thing is to give a compile command to rc. There are roughly two types of methods.

  1. Pass directly with the rc -c command
  1. Pass in the compile_commands.json file with the rc -J command

** Method 1: Pass directly with the rc -c command **

Pass the compile command of the target source file directly to rc as shown below.

$ rc -c g++ a.cpp b.cpp

This is fine for a few source files, but in most cases it's painful to type a command like this every time. Therefore, there is a way to use the wrapper script provided by the author. It is recommended to do the following.

##Create a bin directory in your home directory
$ mkdir ~/bin

##Put at the beginning of the search path
$ echo 'export PATH=${HOME}/bin:${PATH}' >> .bashrc

##Copy wrapper script
$ cp rtags/bin/gcc-rtags-wrapper.sh ~/bin/gcc
$ cp rtags/bin/gcc-rtags-wrapper.sh ~/bin/g++

That way, every time you type the gcc or g ++ command, this wrapper script will actually be called and will execute rc -c internally. Indexing is done every time you compile, which is very convenient. Of course, it does not affect the operation of gcc and g ++.

** Method 2: Load compile_commands.json with rc -J command **

compile_commands.json is a JSON Compilation Database, which is a JSON file that records the information required for compilation. You can index by loading this file into rc

Recent build systems such as cmake and ninja can output JSON Compilation Database at build time, so you can do as follows.

##When using cmake
$ cmake . -DCMAKE_EXPORT_COMPILE_COMMANDS=1
$ rc -J .

##When using ninja
$ ninja -t commands | rc -c -

If you have a small project that only uses GNU Make, you can output the Compilation Database with the help of a tool called Bear. This method is the most recommended personally. Build and install as below.

$ git clone https://github.com/rizsotto/Bear
$ cd Bear
$ mkdir build && cd build
$ cmake ..
$ make && sudo make install

It's easy to use, just type bear before the regular make command. This will output the Compilation Database based on the compile command called from the Makefile.

$ bear make
$ rc -J .

** Use Rtags from Vim **

There is a plugin called vim-rtags. It is still under development, but it still has enough features.

** Installation / Settings **

NeoBundle 'lyuts/vim-rtags'

The default keymap has a lot of strokes and is a little hard to hit. There is a mapping in plugin / rtags.vim, so it's a good idea to refer to this and assign it to another key. I have the following settings.

"Jump to definition
nnoremap <silent> <F3> :call rtags#JumpTo()<CR>
"Jump to reference
nnoremap <silent> <F4> :<C-u>Unite<Space>rtags/references<CR>
"Jump to the beginning if you are in the class / function definition
nnoremap <silent> <F5> :call rtags#JumpToParent()<CR>

** How to use **

Suppose you have already printed compile_commands.json and run rc -J . once. If rdm is not running, start it.

$ rdm --daemon

When I actually move it, it looks like this.

You can jump to the definition as well as to the reference. The list of references opens in a Unite window, so it's easy to narrow down. Rdm also monitors file changes, and when you save the source file, the index is automatically updated at the same time.

** Use Rtags from Emacs **

Rtags comes with a plugin for Emacs made by the author. Please refer to here and here for detailed explanations.

** At the end **

So far, we have explained how to use the indexer for C / C ++ "Rtags". The text editor enables code navigation equal to or better than the IDE, which is a great improvement. Setup is a bit tedious, but if you're using C ++ as your main language, it's definitely worth the effort.

Recommended Posts

Seriously use the strongest C / C ++ indexer "Rtags"
How to use the C library in Python
[C] Use qsort ()