Files
fastwc/scripts/gen-compile-commands.sh
T
2026-08-29 13:57:59 -04:00

53 lines
1.8 KiB
Bash
Executable File

#!/usr/bin/env sh
# Generate compile_commands.json for clangd.
#
# Uses bear when available so every real compile command is captured
# (future-proof as the project grows). Otherwise hand-rolls the single
# entry from the flags in the generated Makefile — one source file, one
# entry, no mysteries.
set -eu
ROOT=$(cd "$(dirname "$0")/.." && pwd)
cd "$ROOT"
if [ ! -f Makefile ]; then
echo "gen-compile-commands: no Makefile found - run ./autogen.sh first" >&2
exit 1
fi
if command -v bear >/dev/null 2>&1; then
bear -- make -B >/dev/null
# Drop the configure probes (conftest.c); clangd only wants real files.
jq 'map(select(.file | endswith("conftest.c") | not))' compile_commands.json \
> compile_commands.json.tmp && mv compile_commands.json.tmp compile_commands.json
echo "compile_commands.json generated via bear"
exit 0
fi
CC=$(sed -n 's/^CC = //p' Makefile | head -n1)
[ -z "$CC" ] && CC=cc
DEFS=$(sed -n 's/^DEFS = //p' Makefile | head -n1)
AM_CFLAGS=$(sed -n 's/^AM_CFLAGS = //p' Makefile | head -n1)
CFLAGS=$(sed -n 's/^CFLAGS = //p' Makefile | head -n1)
# Drop defines carrying embedded quotes (PACKAGE_* metadata): they would
# break JSON and clangd does not need them.
SAFE_DEFS=''
for d in $DEFS; do
case "$d" in
*\"*) ;;
*) SAFE_DEFS="$SAFE_DEFS $d" ;;
esac
done
CMD="$CC$SAFE_DEFS -I. $AM_CFLAGS $CFLAGS -c src/main.c -o src/main.o"
if command -v jq >/dev/null 2>&1; then
jq -n --arg d "$ROOT" --arg c "$CMD" --arg f "$ROOT/src/main.c" \
'[{directory: $d, command: $c, file: $f}]' > compile_commands.json
else
printf '[{"directory":"%s","command":"%s","file":"%s"}]\n' \
"$ROOT" "$CMD" "$ROOT/src/main.c" > compile_commands.json
fi
echo "compile_commands.json generated (fallback)"