diff --git a/content/posts/automatizing-tags.md b/content/posts/automatizing-tags.md new file mode 100644 index 0000000..dbd67b1 --- /dev/null +++ b/content/posts/automatizing-tags.md @@ -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;i1 { for(i=1;i