Generating Clang Compilation Databases on OpenBSD
Clang compilation databases are a really useful
feature if you’re a Vim user and have a code linting plugin like coc.
On my OpenBSD workstation, I use NeoVim and the aforementioned
plugin, so I needed a way to generate the json files that clangd
uses. There are some nice tools in the Linux
world that do this for you, but as usual they don’t support BSDs.
Here’s a script that I wrote for a recent project that generates the compilation database files.
This script assumes that all your .c
files live in $PROJECT_ROOT/src
, tweak the find(1)
usage as necessary.
When using the clang
compiler to generate these files, they spit out a 1:1 match of json files to source files.
Thankfully, a little sed
solves that problem.
#!/usr/bin/env sh
set -e
CFLAGS="-I./include -I/usr/local/include"
rm -f compile_commands.json
for f in $(find ./src -type f); do
n=$(echo $f | grep -o '[^/]*$' | sed 's/c$/json/')
cc -MJ $n $CFLAGS -c $f
done
rm *.o
sed -e '1s/^/[/' -e '$s/,$/]/' *.json > compile_commands.out
rm *.json
mv compile_commands.out compile_commands.json
There is a much easier way to solve this problem if you’re willing to go the Cmake route, which is what I’ve come around to these days. I could write a long diatribe on Cmake, but the short version is that it used to be really bad, but these days it’s pretty good. I like to provide a Makefile that sets up and runs Cmake, and let Cmake handle the actual hard part.
Here’s the template Makefile that I use for any C project. The actual project configuration is then done in
CMakeLists.txt
CMAKE_OPTS=-DCMAKE_EXPORT_COMPILE_COMMANDS=1
all:
mkdir -p build
cd build && \
cmake ${CMAKE_OPTS} .. && \
make && \
cp compile_commands.json ..
clean:
rm -rf build
rm -f compile_commands.json