Feb 2020
By default, running ctags on a C source file only generates tags for
symbols defined inside that very file. I usually find it more convenient
to generate tags for all the symbols in the included header files as
well.
To do this, we can use our C preprocessor’s ability to generate make
targets: cc -M foo.c. I use a very simple search pattern to filter out
only the .c and .h file names and pipe that into ctags.
The whole incantation is relatively simple:
tags() {
${CC:-cc} $CFLAGS -M $@ \
|grep -o '[^ ]*\.[ch]' \
|ctags -L - --kinds-c=+px
}
I put $CFLAGS there to pick up includedirs if necessary (although that
requires the variable to be set appropriate from whatever context this
gets called). ctags requires the -L - option to take filenames from
STDIN. The option --kinds-c=+px adds function prototypes and external
variables to the tagfile.
NOTE: You need to set $CC to a C compiler that supports dependency
generation in Makefile format, like GCC and Clang. GCC’s standalone
preprocessor executable cpp also works.
NOTE: This method will only pickup on conditionally defined symbols and
conditionally included files if the conditions are met. E.g. you could
export a CFLAGS variable, defining the constants that are checked by
those ifdefs.
See also: