From: Daan De Meyer Date: Thu, 24 Apr 2025 09:58:45 +0000 (+0200) Subject: meson: Define our own clang-tidy target X-Git-Tag: v258-rc1~747^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=44e86153d175e336ebd9b916fd31c87770a2198c;p=thirdparty%2Fsystemd.git meson: Define our own clang-tidy target 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. --- diff --git a/.clang-tidy-ignore b/.clang-tidy-ignore deleted file mode 100644 index 6e0889f0807..00000000000 --- a/.clang-tidy-ignore +++ /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 diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 65a121306a5..b4ab5769ae5 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -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 diff --git a/docs/HACKING.md b/docs/HACKING.md index 25ad0aa17e0..dffea56b0f8 100644 --- a/docs/HACKING.md +++ b/docs/HACKING.md @@ -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 +``` diff --git a/meson.build b/meson.build index 9aef6760a34..7458f060a22 100644 --- a/meson.build +++ b/meson.build @@ -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', diff --git a/src/basic/meson.build b/src/basic/meson.build index 3396e395dec..a99f198a974 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -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( diff --git a/src/boot/meson.build b/src/boot/meson.build index e393ed9d744..d4bd202f6fe 100644 --- a/src/boot/meson.build +++ b/src/boot/meson.build @@ -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'), diff --git a/src/core/bpf/restrict_fs/meson.build b/src/core/bpf/restrict_fs/meson.build index 69cde02a7b4..4dcc21f1b43 100644 --- a/src/core/bpf/restrict_fs/meson.build +++ b/src/core/bpf/restrict_fs/meson.build @@ -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 diff --git a/src/core/bpf/restrict_ifaces/meson.build b/src/core/bpf/restrict_ifaces/meson.build index 5f361782286..4ed8a981bb8 100644 --- a/src/core/bpf/restrict_ifaces/meson.build +++ b/src/core/bpf/restrict_ifaces/meson.build @@ -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 diff --git a/src/core/bpf/socket_bind/meson.build b/src/core/bpf/socket_bind/meson.build index 05a2b9daf80..ec845906a77 100644 --- a/src/core/bpf/socket_bind/meson.build +++ b/src/core/bpf/socket_bind/meson.build @@ -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 diff --git a/src/core/meson.build b/src/core/meson.build index 0ae8d8383b1..3db71e19d49 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -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( diff --git a/src/home/meson.build b/src/home/meson.build index 74174dec9ea..7e267dadd38 100644 --- a/src/home/meson.build +++ b/src/home/meson.build @@ -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( diff --git a/src/journal/meson.build b/src/journal/meson.build index 60cde31c86b..c672cbe3278 100644 --- a/src/journal/meson.build +++ b/src/journal/meson.build @@ -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, diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build index 0eb9392d5d0..06b02a2f448 100644 --- a/src/libsystemd/meson.build +++ b/src/libsystemd/meson.build @@ -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 ############################################################ diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c index 92da6272b7a..31b04002b59 100644 --- a/src/libsystemd/sd-bus/test-bus-marshal.c +++ b/src/libsystemd/sd-bus/test-bus-marshal.c @@ -3,8 +3,14 @@ #include #include +/* 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 +DISABLE_WARNING_FORMAT_NONLITERAL +#include /* NOLINT */ +REENABLE_WARNING #endif #if HAVE_DBUS diff --git a/src/login/meson.build b/src/login/meson.build index 2983819c56b..6b617ca4482 100644 --- a/src/login/meson.build +++ b/src/login/meson.build @@ -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', diff --git a/src/network/bpf/sysctl_monitor/meson.build b/src/network/bpf/sysctl_monitor/meson.build index ac8e81e9270..c3ae52a473f 100644 --- a/src/network/bpf/sysctl_monitor/meson.build +++ b/src/network/bpf/sysctl_monitor/meson.build @@ -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 diff --git a/src/network/meson.build b/src/network/meson.build index 0dab9d64f26..5d6fc9a8060 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -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 diff --git a/src/nspawn/meson.build b/src/nspawn/meson.build index 84e80d6e2db..f7fa908806d 100644 --- a/src/nspawn/meson.build +++ b/src/nspawn/meson.build @@ -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', diff --git a/src/nsresourced/bpf/userns_restrict/meson.build b/src/nsresourced/bpf/userns_restrict/meson.build index d773c75859d..a62e34dad28 100644 --- a/src/nsresourced/bpf/userns_restrict/meson.build +++ b/src/nsresourced/bpf/userns_restrict/meson.build @@ -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 diff --git a/src/resolve/meson.build b/src/resolve/meson.build index 076ac680e3e..9353c2da948 100644 --- a/src/resolve/meson.build +++ b/src/resolve/meson.build @@ -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( diff --git a/src/shared/meson.build b/src/shared/meson.build index 88e3f86d263..e206aba851a 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -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' diff --git a/src/test/meson.build b/src/test/meson.build index 9453ddd899e..480ff5e4125 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -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( diff --git a/src/timesync/meson.build b/src/timesync/meson.build index d843ed78bfa..19437ee927c 100644 --- a/src/timesync/meson.build +++ b/src/timesync/meson.build @@ -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 diff --git a/src/udev/meson.build b/src/udev/meson.build index 06fe5620771..412f5729d44 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -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')