]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
meson: Define our own clang-tidy target
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 24 Apr 2025 09:58:45 +0000 (11:58 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 24 Apr 2025 10:36:36 +0000 (12:36 +0200)
meson's target has a few issues:
- Runs on all source files regardless if they're included in the
  build or not
- Doesn't have any dependencies on generated sources which means we
  have to do a full build first before we can run clang-tidy
- Doesn't allow us to pass any extra arguments

To work around these, let's define our own clang-tidy target instead
using llvm's run-clang-tidy script. Alongside the clang-tidy target,
let's start keeping track of all generated sources which we make the
clang-tidy target depend on. We also add a new target which will only
generate source files which is useful for setting up the source tree
for running code analysis against it.

24 files changed:
.clang-tidy-ignore [deleted file]
.github/workflows/linter.yml
docs/HACKING.md
meson.build
src/basic/meson.build
src/boot/meson.build
src/core/bpf/restrict_fs/meson.build
src/core/bpf/restrict_ifaces/meson.build
src/core/bpf/socket_bind/meson.build
src/core/meson.build
src/home/meson.build
src/journal/meson.build
src/libsystemd/meson.build
src/libsystemd/sd-bus/test-bus-marshal.c
src/login/meson.build
src/network/bpf/sysctl_monitor/meson.build
src/network/meson.build
src/nspawn/meson.build
src/nsresourced/bpf/userns_restrict/meson.build
src/resolve/meson.build
src/shared/meson.build
src/test/meson.build
src/timesync/meson.build
src/udev/meson.build

diff --git a/.clang-tidy-ignore b/.clang-tidy-ignore
deleted file mode 100644 (file)
index 6e0889f..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-man/*
-# These contain external headers that we don't want to check.
-src/basic/include/*
-# clang-tidy can't parse BPF source files.
-src/core/bpf/*
-src/network/bpf/*
-src/nsresourced/bpf/*
-# The glib headers contain cyclic dependencies and clang-tidy
-# can't distinguish between our code and glib headers so we
-# exclude this test.
-src/libsystemd/sd-bus/test-bus-marshal.c
index 65a121306a5329474fef2c514342c8b13d91b9a5..b4ab5769ae590358a38810a317aedc5c48da8f66 100644 (file)
@@ -73,9 +73,5 @@ jobs:
       - name: Configure meson
         run: mkosi sandbox -- env CC=clang CXX=clang++ meson setup build
 
-        # Make sure all generated source files are actually generated by doing a full build.
-      - name: Build systemd
-        run: mkosi sandbox -- ninja -C build
-
       - name: Run clang-tidy
         run: mkosi sandbox -- ninja -C build clang-tidy
index 25ad0aa17e0ad73cf5934d561fcca90696485f84..dffea56b0f80668ee6fd3a470c15c0b5fc9f7dd0 100644 (file)
@@ -331,3 +331,11 @@ compilation database used by clangd to use clang as the compiler as well:
 ```sh
 $ mkosi sandbox -- env CC=clang CXX=clang++ meson setup build
 ```
+
+Additionally, the `gensources` target can be used to make sure all generated
+sources are generated to avoid clangd complaining that these source files don't
+exist.
+
+```sh
+$ mkosi sandbox -- ninja -C build gensources
+```
index 9aef6760a34dd3510b9459fde609d33c603fc75f..7458f060a22c8fcd1a48cc2130ad285c3eb3dee7 100644 (file)
@@ -1911,11 +1911,11 @@ if conf.get('BPF_FRAMEWORK') == 1
         endif
 endif
 
+vmlinux_h_dependency = []
 if use_provided_vmlinux_h
         if not fs.exists(provided_vmlinux_h_path)
                 error('Path to provided vmlinux.h does not exist.')
         endif
-        vmlinux_h_dependency = []
         bpf_o_unstripped_cmd += ['-I' + fs.parent(provided_vmlinux_h_path)]
         message('Using provided @0@'.format(provided_vmlinux_h_path))
 elif use_generated_vmlinux_h
@@ -2008,6 +2008,7 @@ modules = [] # nss, pam, and other plugins
 executables = []
 executables_by_name = {}
 fuzzer_exes = []
+generated_sources = [version_h, vmlinux_h_dependency]
 
 # binaries that have --help and are intended for use by humans,
 # usually, but not always, installed in /bin.
@@ -2864,6 +2865,27 @@ endif
 
 #####################################################################
 
+alias_target('gensources', generated_sources)
+
+run_clang_tidy = find_program('run-clang-tidy', required : false)
+if run_clang_tidy.found()
+        run_target(
+                'clang-tidy',
+                command : [
+                        run_clang_tidy,
+                        '-use-color',
+                        '-quiet',
+                        '-p', meson.project_build_root(),
+                        # There seems to be a bug in clang-tidy where by even with --quiet some
+                        # messages from clang's own diagnostics engine leak through:
+                        #     X warnings generated.
+                        # Until this is fixed upstream, we use -fno-caret-diagnostics to suppress these.
+                        '-extra-arg=-fno-caret-diagnostics',
+                ],
+                depends : generated_sources
+        )
+endif
+
 check_api_docs_sh = find_program('tools/check-api-docs.sh')
 run_target(
         'check-api-docs',
index 3396e395decfab6b536bf26ec52ce8fdc771d23a..a99f198a974b1a781a1b65e3c304ffeaf7f1df58 100644 (file)
@@ -189,6 +189,7 @@ foreach item : [['af',     af_list_txt,     'af',         ''],
         generated_gperf_headers += [target1, target2]
 endforeach
 
+generated_sources += generated_gperf_headers
 basic_sources += generated_gperf_headers
 
 ############################################################
@@ -274,6 +275,7 @@ filesystem_switch_case_h = custom_target(
                    '@INPUT@'],
         capture : true)
 
+generated_sources += [filesystem_list_h, filesystem_switch_case_h, filesystems_gperf_h]
 basic_sources += [filesystem_list_h, filesystem_switch_case_h, filesystems_gperf_h]
 
 libbasic_static = static_library(
index e393ed9d744f2422462b84d4e78b1a6ebc2c4e4a..d4bd202f6fef57f68ebf1153d120b4ec7131143e 100644 (file)
@@ -37,9 +37,11 @@ if conf.get('ENABLE_UKIFY') == 1
                 capture : true,
                 build_by_default : want_tests != 'false')
 else
-        test_hwids_section_c = ''
+        test_hwids_section_c = []
 endif
 
+generated_sources += test_hwids_section_c
+
 executables += [
         efi_test_template + {
                 'sources' : files('test-bcd.c'),
index 69cde02a7b47d29eecf84ae875bd623887d30907..4dcc21f1b43083c3ad9c4ff52ab8a3920d610465 100644 (file)
@@ -22,3 +22,5 @@ restrict_fs_skel_h = custom_target(
         output : 'restrict-fs.skel.h',
         command : skel_h_cmd,
         capture : true)
+
+generated_sources += restrict_fs_skel_h
index 5f36178228644d22a9ea4da96a06af150ad28f89..4ed8a981bb8a73cd61c1d61d1dfe78b9754dce60 100644 (file)
@@ -22,3 +22,5 @@ restrict_ifaces_skel_h = custom_target(
         output : 'restrict-ifaces.skel.h',
         command : skel_h_cmd,
         capture : true)
+
+generated_sources += restrict_ifaces_skel_h
index 05a2b9daf80344bd62549e108b3609977b3876b4..ec845906a776d85709745529c70f87ebc0ae2f3a 100644 (file)
@@ -22,3 +22,5 @@ socket_bind_skel_h = custom_target(
         output : 'socket-bind.skel.h',
         command : skel_h_cmd,
         capture : true)
+
+generated_sources += socket_bind_skel_h
index 0ae8d8383b19b2dbef2c683c064cc75f0cea5aa8..3db71e19d4944c6fa2a9c3c6862cc2b34bfea960 100644 (file)
@@ -102,6 +102,8 @@ load_fragment_gperf_nulstr_c = custom_target(
         command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
         capture : true)
 
+generated_sources += [load_fragment_gperf_c, load_fragment_gperf_nulstr_c]
+
 libcore_name = 'systemd-core-@0@'.format(shared_lib_tag)
 
 libcore_static = static_library(
index 74174dec9ea65adca95a9b953e77e695f7c144c1..7e267dadd3891deac8e86e21034cddbc056f7696 100644 (file)
@@ -47,6 +47,7 @@ homed_gperf_c = custom_target(
         output : 'homed-gperf.c',
         command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
 
+generated_sources += [homed_gperf_c]
 systemd_homed_sources += [homed_gperf_c]
 
 homectl_sources = files(
index 60cde31c86b5e62d6ee80ab08b14ed3921a3c826..c672cbe3278042b5b74f7cfc2dad4b9608d20ac8 100644 (file)
@@ -16,12 +16,15 @@ sources = files(
         'journald-wall.c',
 )
 
-sources += custom_target(
+journald_gperf_c = custom_target(
         'journald-gperf.c',
         input : 'journald-gperf.gperf',
         output : 'journald-gperf.c',
         command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
 
+generated_sources += journald_gperf_c
+sources += journald_gperf_c
+
 libjournal_core = static_library(
         'journal-core',
         sources,
index 0eb9392d5d0ecf3abaa60b9519537c52f4fd43eb..06b02a2f44822d773b821e00fe9a9aa6964f70df 100644 (file)
@@ -35,7 +35,8 @@ audit_type_to_name = custom_target(
         command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
         capture : true)
 
-sd_journal_sources += [audit_type_to_name]
+generated_sources += audit_type_to_name
+sd_journal_sources += audit_type_to_name
 
 ############################################################
 
index 92da6272b7aeaa7c865b6a79ab2222b44aee1c0e..31b04002b5919cb961bd5a1c9a468cf971c069b6 100644 (file)
@@ -3,8 +3,14 @@
 #include <math.h>
 #include <stdlib.h>
 
+/* We make an exception here to our usual "include system headers first" rule because we need one of these
+ * macros to disable a warning triggered by the glib headers. */
+#include "macro-fundamental.h"
+
 #if HAVE_GLIB
-#include <gio/gio.h>
+DISABLE_WARNING_FORMAT_NONLITERAL
+#include <gio/gio.h> /* NOLINT */
+REENABLE_WARNING
 #endif
 
 #if HAVE_DBUS
index 2983819c56bd7f5d567a8f83cef7b7affae6ad80..6b617ca4482956d3013176d2896dc0c224602a50 100644 (file)
@@ -10,6 +10,8 @@ logind_gperf_c = custom_target(
         output : 'logind-gperf.c',
         command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
 
+generated_sources += logind_gperf_c
+
 liblogind_core_sources = files(
         'logind-action.c',
         'logind-brightness.c',
index ac8e81e92703804a753225595130300b3a7ecf0f..c3ae52a473fc12f290a9bff7f3cf3800d4231204 100644 (file)
@@ -23,3 +23,5 @@ sysctl_monitor_skel_h = custom_target(
         output : 'sysctl-monitor.skel.h',
         command : skel_h_cmd,
         capture : true)
+
+generated_sources += sysctl_monitor_skel_h
index 0dab9d64f2669f1ba27f2bbceced80e337a5523c..5d6fc9a806004d3fd746bbef154f66b87298e5fa 100644 (file)
@@ -148,24 +148,27 @@ if conf.get('HAVE_VMLINUX_H') == 1
         sources += sysctl_monitor_skel_h
 endif
 
-sources += custom_target(
+networkd_gperf_c = custom_target(
         'networkd-gperf.c',
         input : 'networkd-gperf.gperf',
         output : 'networkd-gperf.c',
         command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
 
-sources += custom_target(
+networkd_network_gperf_c = custom_target(
         'networkd-network-gperf.c',
         input : networkd_network_gperf_gperf,
         output : 'networkd-network-gperf.c',
         command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
 
-sources += custom_target(
+netdev_gperf_c = custom_target(
         'netdev-gperf.c',
         input : networkd_netdev_gperf_gperf,
         output : 'netdev-gperf.c',
         command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
 
+generated_sources += [networkd_gperf_c, networkd_network_gperf_c, netdev_gperf_c]
+sources += [networkd_gperf_c, networkd_network_gperf_c, netdev_gperf_c]
+
 if get_option('link-networkd-shared')
         networkd_link_with = [libshared]
 else
index 84e80d6e2db794935cf36910fc5dcfe99a81c311..f7fa908806d62cb0fd69e330aac6a37e0d60fd84 100644 (file)
@@ -20,7 +20,8 @@ nspawn_gperf_c = custom_target(
         output : 'nspawn-gperf.c',
         command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
 
-libnspawn_core_sources += [nspawn_gperf_c]
+generated_sources += nspawn_gperf_c
+libnspawn_core_sources += nspawn_gperf_c
 
 libnspawn_core = static_library(
         'nspawn-core',
index d773c75859d010c6ee0321e631a2fe118723cbd2..a62e34dad28a36705ac2e33b33c6c6730ff09b25 100644 (file)
@@ -23,3 +23,5 @@ userns_restrict_skel_h = custom_target(
         output : 'userns-restrict.skel.h',
         command : skel_h_cmd,
         capture : true)
+
+generated_sources += userns_restrict_skel_h
index 076ac680e3e5909386a219d22b310a436ae4cf30..9353c2da948098e3f2192a5d792ebc905b853c29 100644 (file)
@@ -62,7 +62,7 @@ gperf_file = custom_target(
         command : [generate_dns_type_gperf, 'dns_type', 'DNS_TYPE_', '@INPUT@'],
         capture : true)
 
-basic_dns_sources += custom_target(
+dns_type_from_name_h = custom_target(
         'dns_type-from-name.h',
         input : gperf_file,
         output : 'dns_type-from-name.h',
@@ -74,13 +74,16 @@ basic_dns_sources += custom_target(
                    '@INPUT@'],
         capture : true)
 
-basic_dns_sources += custom_target(
+dns_type_to_name_h = custom_target(
         'dns_type-to-name.h',
         input : ['dns_type-to-name.awk', dns_type_list_txt],
         output : 'dns_type-to-name.h',
         command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
         capture : true)
 
+generated_sources += [dns_type_from_name_h, dns_type_to_name_h]
+basic_dns_sources += [dns_type_from_name_h, dns_type_to_name_h]
+
 libsystemd_resolve_core = static_library(
         'systemd-resolve-core',
         basic_dns_sources,
@@ -88,18 +91,21 @@ libsystemd_resolve_core = static_library(
         dependencies : userspace,
         build_by_default : false)
 
-systemd_resolved_sources += custom_target(
+resolved_gperf_c = custom_target(
         'resolved_gperf.c',
         input : 'resolved-gperf.gperf',
         output : 'resolved-gperf.c',
         command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
 
-systemd_resolved_sources += custom_target(
+resolved_dnssd_gperf_c = custom_target(
         'resolved_dnssd_gperf.c',
         input : 'resolved-dnssd-gperf.gperf',
         output : 'resolved-dnssd-gperf.c',
         command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
 
+generated_sources += [resolved_gperf_c, resolved_dnssd_gperf_c]
+systemd_resolved_sources += [resolved_gperf_c, resolved_dnssd_gperf_c]
+
 systemd_resolved_dependencies = [threads, libm, libopenssl]
 if conf.get('ENABLE_DNS_OVER_TLS') == 1
         systemd_resolved_sources += files(
index 88e3f86d263b787aeebb88a71e8789e535edc762..e206aba851a42caed110c1844bc06955cbef2b28 100644 (file)
@@ -231,6 +231,8 @@ syscall_list_h = custom_target(
                    '@INPUT@'],
         capture : true)
 
+generated_sources += syscall_list_h
+
 if conf.get('HAVE_ACL') == 1
         shared_sources += files('devnode-acl.c')
 endif
@@ -302,6 +304,7 @@ target2 = custom_target(
         capture : true)
 
 shared_generated_gperf_headers = [target1, target2]
+generated_sources += shared_generated_gperf_headers
 shared_sources += shared_generated_gperf_headers
 
 fname = 'ethtool-link-mode.h'
@@ -311,6 +314,8 @@ ethtool_link_mode_h = custom_target(
         output : fname,
         command : [python, '@INPUT0@', '--header', cpp, '@INPUT1@'],
         capture : true)
+
+generated_sources += ethtool_link_mode_h
 shared_sources += ethtool_link_mode_h
 
 fname = 'ethtool-link-mode.xml'
index 9453ddd899e6a13e5cce8d37d61ee6f7a31cd4e6..480ff5e4125f250a43d9b3fd70612d528d7cb585 100644 (file)
@@ -9,6 +9,8 @@ test_hashmap_ordered_c = custom_target(
         capture : true,
         build_by_default : want_tests != 'false')
 
+generated_sources += test_hashmap_ordered_c
+
 path = run_command(sh, '-c', 'echo "$PATH"', check: true).stdout().strip()
 test_env = environment()
 test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map)
@@ -41,6 +43,8 @@ test_libudev_sym_c = custom_target(
         capture : true,
         build_by_default : want_tests != 'false')
 
+generated_sources += [test_libsystemd_sym_c, test_libudev_sym_c]
+
 ############################################################
 
 simple_tests += files(
index d843ed78bfa4292672e48426ec1ec5f8204cc972..19437ee927cea68b276112685205bfccfd3c6dce 100644 (file)
@@ -11,12 +11,15 @@ systemd_timesyncd_sources = files(
         'timesyncd-bus.c',
 )
 
-sources += custom_target(
+timesyncd_gperf_c = custom_target(
         'timesyncd-gperf.c',
         input : 'timesyncd-gperf.gperf',
         output : 'timesyncd-gperf.c',
         command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
 
+generated_sources += timesyncd_gperf_c
+sources += timesyncd_gperf_c
+
 if get_option('link-timesyncd-shared')
         timesyncd_link_with = [libshared]
 else
index 06fe562077184cdae890174b0d3d1631802fcdc6..412f5729d44fa4c96acdd4e56f3b928459835ad2 100644 (file)
@@ -92,6 +92,8 @@ keyboard_keys_from_name_h = custom_target(
                    '@INPUT@'],
         capture : true)
 
+generated_sources += keyboard_keys_from_name_h
+
 ############################################################
 
 udev_link_gperf_gperf = files('net/link-config-gperf.gperf')
@@ -102,6 +104,8 @@ link_config_gperf_c = custom_target(
         output : 'link-config-gperf.c',
         command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
 
+generated_sources += link_config_gperf_c
+
 ############################################################
 
 if get_option('link-udev-shared')