I am accustomed to using Vim for code navigation, and I can confidently assert that there is no code browser faster than Vim when paired with cscope and ctags, provided it is configured correctly. Although I began writing this blog some time ago, I was unable to complete it with all the essential elements due to other commitments. Unfortunately, I also couldn’t find the time to revisit it recently. Therefore, this marks another attempt to refine it, specifically by incorporating a few crucial additions. Here are few steps to follow to setup your cscope as well as ctag database before you can start surfing the source code using the vim editor.

#!/bin/bash
find -type f -iname ‘*.c’ -o -iname ‘*.cpp’ -o -iname ‘*.h’ -o -iname ‘*.hpp’ -o -iname ‘*.cc’ -o -iname ‘*.hh’  -type f  > ./cscope.files
cscope -q -R -b -i ~/cscope.files -f ./cscope.out
export CSCOPE_DB=~/cscope.out
ctags -R .

You can download the above setup file from the following github link as well: setup_cscope.

The customization of the cscope database file path can be tailored to suit your specific environment. In this particular example, I have opted for the current working directory, specified as “./,” as the designated location for both the cscope and ctags databases. It is crucial to thoughtfully decide where these databases will reside, particularly when working on multiple projects or repositories. While a shared location may seem convenient, it is impractical as it risks overwriting previous databases. Consequently, I find it more practical to designate the top-level directory of the source code as the repository for the corresponding database. This approach enhances generality and simplifies management. While perspectives may vary, this is the method I am currently convinced of, and I will adhere to it throughout this blog.

Working with Multiple directories

You can specify multiple directory to find command above. See below:

$find misc/xxxx/abc/ net/wireless/xyz/ ../../../kernel/topic/include/ -type f -iname '*.c' -o -iname '*.cpp' -o -iname '*.h' -o -iname '*.hpp' -o -iname '*.cc' -o -iname '*.hh' -type f > ~/cscope.files

By default ctrl-] doesn’t look into the cscope database rather it looks into the ctag database. So you may come across the following error message while trying to go to a sysmbol definition:

Error tag not found

So to search in catg database add the following in your .vimrc file:

set cscopetag

After opening a vim session do the below:

set cscopetag

You also need to add the cscope database and let vim know it is located using the following vim command:

cs add $CSCOPE_DB

Remember $CSCOPE_DB we set in the script and pointed to the location where out cscope database is located previously.

cscope database location

In this configuration the CSCOPE_DB will point to either ~/cscope.out or ./cscope.out. But if you were to start working with a different code base at a later point of time, you have to regenerate your cscope.out file as described above. You can place the cscope.out file anywhere you like but you have to keep in mind the CSCOPE_DB should be pointing to that location. For example if you decide to place it under /home/xyz/abc instead of ~/ then in your environment the CSCOPE_DB should be set as:

export CSCOPE_DB=/home/xyz/abc/cscope.out

Or you may choose to use the top level directory of a certain code base as the database location as I do for my puposes. It is entirely up to the developer and you may choose to keep it wherever you like.

Excluding folders from the cscope database

Sometime you may not want to include certain folder(s) from your cscope databse. For example, if you are familiar with buildroot way of working, the output folder is something you may not like to include in you cscope database. To exclude the output folder from the cscope database I execute the following steps:

#!/bin/bash
find -type d -path ./output -prune -type f -iname '*.c' -o -iname '*.cpp' -o -iname '*.h' -o -iname '*.hpp' -o -iname '*.cc' -o -iname '*.hh' -type f > ./cscope.files
cscope -q -R -b -i ./cscope.files -f ./cscope.out
ctags --exclude=output --exclude=package --exclude=system -R .
export CSCOPE_DB=./cscope.out

The trick is done by the following option in the find command:

-path ./output -prune

Also, if you noticed I have changed the ctag options in the above steps. I have added the following in in the options while creating ctag database:

--exclude=output --exclude=package --exclude=system

The options above excludes the following folders output, package and system from the ctag database and keeps the noise low. I have added the modified script here: setup_cscope_improved.

Leave a Reply