Tags post
This commit is contained in:
parent
6201e14a9e
commit
3039334838
1 changed files with 40 additions and 0 deletions
40
content/posts/automatizing-tags.md
Normal file
40
content/posts/automatizing-tags.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
---
|
||||
title: "Automatizing tags using Make and GCC"
|
||||
date: 2021-04-29
|
||||
draft: false
|
||||
---
|
||||
I've been messing around with LSP and tag systems lately, trying to make my Emacs setup feel a little more /comfy/. However, try as I might, making LSP servers find all project headers with [ccls](https://github.com/MaskRay/ccls) has proven harder than it has any right to be.
|
||||
|
||||
You see, all LSP solutions that I am aware of have a bitch of a time dealing with non-cmake projects. I shun away from complicated build tools, favoring makefiles and simple shell scripts in my projects, and I really don't feel like switching to CMake just for source indexing. I tried using [Bear](https://github.com/rizsotto/Bear) to generate a `compile_commands.json` file that `ccls` could parse, but it still didn't like my project.
|
||||
|
||||
Then I went back to [GNU Global](https://www.gnu.org/software/global/), the superior tagging solution as far as I researched, which I had [already used](https://github.com/Phireh/ast3roiDS/wiki/Syntax-Highlighting) (or tried to. I didn't really get the difference between syntax highlighting and source indexing back in the day). However, even if `global` is the superior choice for tags, I find the `gtags` generation annoying and difficult. It *really* doesn't want you to generate tags from files outside the root source directory. Doing so requires its own tag generation *for each* include path, and that you declare an environment variable `GTAGSLIBPATH` with a list of tagged directories... not ideal for what I'd like to be an automated step.
|
||||
|
||||
The funny thing is, `gtags` _can_ receive a list of files to be tagged as input, in case you had the path of every file needed by your project. It just _refuses_ to work with it. It will spit something like this to you:
|
||||
|
||||
```Warning: '/usr/include/FLAC/all.h' is out of source tree. ignored.```
|
||||
|
||||
... why?
|
||||
|
||||
# Back to ctags
|
||||
|
||||
The good ol' ctags does not seem to have this strange limitation. The command `ctags -L` accepts a list of filenames to be tagged as input, and it does not discriminate files outside the root source tree.
|
||||
|
||||
Only problem being, is there a way to automate such a process? Actually, it is!
|
||||
|
||||
Some time ago I delved into [GCC's preprocessor flags](https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html) and options `-M` and `-MM` caught my eye. They ask the compiler for a list of all included files after preprocessing, without actually compiling the code. Only problem is, they're designed for GNU Makefile in mind, so we'd need to edit the output of `GCC -M` before using it.
|
||||
|
||||
Just as I was finishing my `awk` oneliner, I found out that [I am not the first person to have thought of this](https://www.topbug.net/blog/2012/03/17/generate-ctags-files-for-c-slash-c-plus-plus-source-files-and-all-of-their-included-header-files/). Props to you, Hong Xu. Even though I'm not first to this, I discovered a cool programmer blog.
|
||||
|
||||
Still, I find my solution (using a makefile rule) comfier than his script. Here it is, in all its glory:
|
||||
|
||||
```make
|
||||
tags:
|
||||
@$(CC) $(CFLAGS) $(LIBS) $(INCLUDES) -M $(SOURCES) | awk 'NR==1 { for (i=2;i<NF;++i) print $$i } NR>1 { for(i=1;i<NF;++i) print $$i }' | ctags -L -
|
||||
```
|
||||
|
||||
Some things to note:
|
||||
|
||||
1. `$$` tells `make` to escape the `$` character, so it can be passed to `awk`.
|
||||
1. Replace `ctags` with `etags` depending on your editor.
|
||||
1. If you don't have `awk` on hand you could just use Xu's sed commands.
|
||||
1. You can replace `-M` with `-MM` if you don't feel like you need to tag the system's headers.
|
||||
Loading…
Add table
Add a link
Reference in a new issue