rpav / cmake-build.el

CMake building with multiple targets, run configurations, and interactive menu
GNU General Public License v3.0
14 stars 5 forks source link

generate and symlink compile_commands.json, close #18 #19

Closed dlyr closed 4 years ago

dlyr commented 4 years ago

This PR ask cmake to generate compile_commands.json in build dir and create a symlink in project root. So lsp and other source indexer can used compile_commands.json to do their job.

The modifications are extracted from my own repo, so please test/confirm it works (and is helpfull) before merge. This PR should close #18

rpav commented 4 years ago

This needs to:

Note in the general case this may not be extremely useful; for instance, I have a compile_commands.json I generate at the top level of my vcs directory that combines all other generated files and does some filtering. This means you're not stuck in one project or using multiple clangd for all your various project source. (Really, there should be a utility that does nothing but manage all of this independently.)

dlyr commented 4 years ago

Fine for me, I have no time for the moment to polish this PR, but I understand your requests. How do you generate you "meta compile_commands.json" because I can switch to that, it sounds interesting. (and could also close the issue ...) When you speak about an utility you mean an emacs pkg outside cmake-build.el ?

rpav commented 4 years ago

I'm actually using a number of external scripts, not an emacs thing specifically .. unfortunately one of them is a "waitfile" script that is not published, but you could possibly mimic it with inotifywait or similar:

wait-compile-commands.sh:

#!/bin/bash
dirs=(`find . -type d -wholename '*/build/clang-Debug' -o -wholename '*/build/clangd'`)
params=()

for d in ${dirs[@]}; do
    params+=(-d $d)
done

waitfile ${params[@]} -f compile_commands.json concat-compile-commands.sh

concat-compile-commands.sh:

#!/bin/bash

rm -f compile_commands.json

find . -name compile_commands.json -exec cat {} \; \
    | sed 's/-Xclang -include-pch -Xclang.*\.pch//g' \
    | jq -s '[.[][]]' > compile_commands.json

This uses jq to slice and dice the json, and some sed to remove all the pch references ... clangd (and ccls) really doesn't like PCH. (It's possible to maintain a separate build dir just for non-PCH, but that gets annoying quickly.)

This may be a slow first run until you warm up your fs cache. Also of course if you add a new project/build you'll have to re-run the first to find it.

The waitfile usage here is pretty simple .. it just waits on a fixed list of compile_command.json and runs the given shell command when one of them changes. Any of the other utilities should easily replicate this.

dlyr commented 4 years ago

Here is a proposal, feel free to ask for modifications if it do not answer your expectations.

rpav commented 4 years ago

Looks good, I'll add the relative bit in a bit.