]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bpf: register compile_commands.json entries for bpf programs
authorDaan De Meyer <daan@amutable.com>
Tue, 21 Apr 2026 20:31:22 +0000 (20:31 +0000)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 22 Apr 2026 14:49:36 +0000 (16:49 +0200)
compile_commands.json is generated by ninja from c_COMPILER rules, so
BPF programs (built via custom_target and thus emitted as CUSTOM_COMMAND
rules) never show up there. Clangd consequently falls back to
heuristics when opening .bpf.c files, with poor diagnostic fidelity.

Register a meson postconf script per BPF program that upserts an entry
into compile_commands.json using the same argv meson constructed for
the custom_target. The script runs after meson has written the DB,
substitutes @INPUT@/@OUTPUT@, and keys entries by source path so
repeated reconfigures don't accumulate duplicates.

src/bpf/merge-bpf-compdb.py [new file with mode: 0755]
src/bpf/meson.build

diff --git a/src/bpf/merge-bpf-compdb.py b/src/bpf/merge-bpf-compdb.py
new file mode 100755 (executable)
index 0000000..c93e685
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+import json
+import os
+import sys
+
+
+def main() -> int:
+    build_root = os.environ['MESON_BUILD_ROOT']
+
+    sep = sys.argv.index('--')
+    sources = sys.argv[1:sep]
+    command = sys.argv[sep + 1:]
+
+    db_path = os.path.join(build_root, 'compile_commands.json')
+    try:
+        with open(db_path) as f:
+            db = json.load(f)
+    except FileNotFoundError:
+        db = []
+
+    sources_set = set(sources)
+    db = [entry for entry in db if entry['file'] not in sources_set]
+
+    for source in sources:
+        db.append({
+            'directory': build_root,
+            'file': source,
+            'arguments': [source if a == '@INPUT@' else a for a in command],
+        })
+
+    with open(db_path, 'w') as f:
+        json.dump(db, f, indent=2)
+
+    return 0
+
+
+if __name__ == '__main__':
+    sys.exit(main())
index 54b3027a97ceab590ff923de745ae7749f638a0f..32ab32e93dcdba55e843d01fb130c3ea74a81f56 100644 (file)
@@ -343,6 +343,7 @@ bpf_programs = [
 ]
 
 bpf_programs_by_name = {}
+bpf_sources = []
 
 foreach program : bpf_programs
         if conf.get(program['condition']) != 1
@@ -350,6 +351,7 @@ foreach program : bpf_programs
         endif
 
         source = program['source'][0]
+        # Strip .bpf.c extension
         name = fs.stem(fs.stem(source))
 
         bpf_o_unstripped = custom_target(
@@ -382,4 +384,14 @@ foreach program : bpf_programs
 
         bpf_programs_by_name += { name : skel_h }
         generated_sources += skel_h
+        bpf_sources += source
 endforeach
+
+if bpf_sources.length() > 0
+        meson.add_postconf_script(
+                python,
+                files('merge-bpf-compdb.py'),
+                bpf_sources,
+                '--',
+                bpf_o_unstripped_cmd)
+endif